Cộng đồng chia sẻ tri thức Lib24.vn

Ứng dụng thiết kế web

f8c8a82de157b07f94d38b41227d5b5f
Gửi bởi: Trường Cao Đẳng Cơ Điện Hà Nội 12 tháng 1 2022 lúc 16:00:19 | Được cập nhật: 21 tháng 4 lúc 21:13:00 | IP: 100.117.8.155 Kiểu file: DOCX | Lượt xem: 93 | Lượt Download: 1 | File size: 2.963551 Mb

Nội dung tài liệu

Tải xuống
Link tài liệu:
Tải xuống

Các tài liệu liên quan


Có thể bạn quan tâm


Thông tin tài liệu

Bài 1: Lựa chọn đề tài

Khảo sát nhu cầu

Công ty ABC có nhu cầu thuê bạn xây dựng một trang web về tin tức để giới thiệu các thông tin cũng như các sản phẩm của công ty.

Đặc tả bài toán

Nhiệm vụ của bạn cần thiết kế cơ sở dữ liệu và xây dựng website thực hiện được các chức năng sau đây:

  • Thiết kế các bảng csdl theo yêu cầu bài toán.

  • Thiết kế giao diện website

  • Thiết kế chức năng quản lý người dùng

    • Đăng ký

    • Đăng nhập

    • Đăng xuất

  • Thiết kế chức năng quản lý chuyên mục

    • Thêm chuyên mục

    • Sửa chuyên mục

    • Xoá chuyên mục

  • Thiết kế chức năng quản lý bài viết

    • Thêm bài viết

    • Sửa bài viết

    • Xoá bài viết

  • Thiết kế chức năng hiển thị

    • Hiển thị bài viết

    • Hiển thị chuyên mục

Yêu cầu kỹ thuật:

  • Ngôn ngữ lập trình: HTML, CSS, JavaScript, PHP

  • Lập trình hướng đối tượng; Lập trình theo mô hình MVC

Bài 2: Thiết kế Database và xây dựng bố cục website

Giới thiệu

Để làm một Blog Tin Tức chúng ta sẽ tạo các bảng sau: userscategoriesposts.

Trong đó:

  1. Bảng users: chứa thông tin tài khoản thành viên trong Blog.

  2. Bảng categories: chứa các chuyên mục của Blog.

  3. Bảng posts: chứa các bài viết của Blog.

Bảng users:

Bảng categories:

Bảng posts:

2. Tạo bảng cho Database

Sau khi bạn tải và cài đặt xong Xammp Server, truy cập vào phpmyadmin để bắt đầu tạo bảng theo đường dẫn: http://localhost/phpmyadmin/index.php

Bước 1: Tạo một database tên là blog

Bước 2:

Chạy lệnh SQL sau để tạo bảng users:

CREATE TABLE `blog`.`users` ( `id` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR(20) NOT NULL COMMENT 'tên đăng nhập' , `password` VARCHAR(20) NOT NULL COMMENT 'mật khẩu' , `full_name` VARCHAR(50) NOT NULL COMMENT 'tên đầy đủ' , `level` INT NOT NULL DEFAULT '0' COMMENT 'quyền' , PRIMARY KEY (`id`)) ENGINE = InnoDB;

Chạy lệnh SQL để tạo bảng categories:

CREATE TABLE `blog`.`categories` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(500) NOT NULL COMMENT 'tên chuyên mục' , `slug` VARCHAR(500) NOT NULL COMMENT 'tên chuyên mục không dấu' , PRIMARY KEY (`id`)) ENGINE = InnoDB;

Chạy lệnh SQL để tạo bảng posts:  

CREATE TABLE `blog`.`posts` ( `id` INT NOT NULL AUTO_INCREMENT , `title` VARCHAR(500) NOT NULL COMMENT 'tiêu đề bài viết' , `slug` VARCHAR(500) NOT NULL COMMENT 'tiêu đề không dấu' , `view_number` INT NOT NULL COMMENT 'lượt xem' , `image` VARCHAR(500) NOT NULL COMMENT 'ảnh' , `summary` TEXT NOT NULL COMMENT 'tóm tắt' , `content` LONGTEXT NOT NULL COMMENT 'nội dung' , `category_id` INT NOT NULL COMMENT 'id chuyên mục' , `user_id` INT NOT NULL COMMENT 'id thành viên' , `date` DATE NOT NULL COMMENT 'thời gian đăng' , PRIMARY KEY (`id`)) ENGINE = InnoDB;

3. Xây dựng bố cục thư mục

Trong quá trình xây dựng và phát triển một dự án ngoài việc lựa chọn công nghệ, lựa chọn các thư viện hỗ trợ... thì việc tổ chức các thư mục, các thành phần, cấu trúc của project là việc cực kì quan trọng, nó là một trong những công việc cần phải thực hiện đầu tiên trước khi bạn bắt tay vào việc coding.

Lợi ích của một project có cấu trúc chặc chẽ:

  • Source code dễ nhìn, dễ hiểu(điều này sẽ rất có lợi cho những người mới vào sau dễ dàng làm quen với dự án hơn)

  • Việc quản lý, bảo trì project sẽ trở nên dễ dàng và hiệu quả

  • Và điều cuối cùng nó sẽ giúp cho project của chúng ta nhìn trờ nên chuyên nghiệp hơn

Xây dựng bố cục

Trong bài học này chúng ta sẽ bắt đầu xây dựng bố cục thư mục của Blog Tin tức. Thông thường các project của chúng ta sẽ chia thành các loại như sau:

Trong đó:

  1. Folder Controller: sẽ chứa các file có chức năng nhận request từ client, điều phối các Model và View để có thể cho ra output thích hợp và trả kết quả về cho người dung.

  2. Folder Lib: sẽ chứa nhưng thư viện hoặc những function.

  3. Folder Model: chứa các file có chức năng giao tiếp, truy vấn tới sơ sở dữ liệu.

  4. Folder Public: chứa hình ảnh, css, font,....

  5. Folder View: chứa các file xử lý giao diện.

  6. File Index.php: là file chính của của chúng ta, file này có tác dụng nhận các request để điều hướng đến các View và Controller tương ứng để xử lý.

Bài 3: Lập trình các chức năng

Tạo kết nối với CSDL

Tạo kết nối

Đầu tiên chúng ta tạo file Database.php trong folder Model và copy và paste đoạn code dưới đây:

<?php

class Database

{

public $conn = NULL;

private $server = 'localhost';

private $dbName = 'blog';

private $user = 'root';

private $password = '';

// Hàm kết nối CSDL

public function connect()

{

$this->conn = new mysqli($this->server, $this->user, $this->password, $this->dbName);

if ($this->conn->connect_error) {

printf($this->conn->connect_error);

exit();

}

$this->conn->set_charset("utf8");

}

// Hàm đóng kết nối CSDL

public function closeDatabase()

{

if ($this->conn) {

$this->conn->close();

}

}

}

Gọi hàm kết nối

Sau khi kết nối xong với CSDL, chúng ta viết đoạn code dưới đây vào file index.php

<?php

require('Model/Database.php');

$db = new Database;

$db->connect();

/*Xử lý các request*/

$db->closeDatabase();

Thiết kế giao diện cho trang Admin

Sau khi tạo kết nối với Database thành công, chúng ta bắt đầu thiết kế giao diện cho trang quản trị Admin

Download template Admin tại đây.

Thiết lập bố cục folder

Sau khi đã tải template, giải nén bằng winrar hoặc 7-zip được folder AdminLTE-master.

Copy toàn bộ folder dist và plugins trong AdminLTE-master vào thư mục Public/admin.

Tiếp tục tạo các file và folder như hình vẽ dưới đây:

Thiết kế trang chủ Admin

Sau khi đã tạo bố cục cho trang chủ xong chúng ta bắt đầu tiến hành viết code cho từng file.

File header.php: copy và paste đoạn code sau vào file header.php (đường dẫn: blog/View/admin/layouts/header.php)  

<!DOCTYPE >

<>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title>AdminLTE 3 | Dashboard</title>

<!-- Tell the browser to be responsive to screen width -->

<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Font Awesome -->

<link rel="stylesheet" href="../../Public/admin/plugins/fontawesome-free/css/all.min.css">

<!-- Ionicons -->

<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">

<!-- Tempusdominus Bbootstrap 4 -->

<link rel="stylesheet" href="../../Public/admin/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">

<!-- iCheck -->

<link rel="stylesheet" href="../../Public/admin/plugins/icheck-bootstrap/icheck-bootstrap.min.css">

<!-- JQVMap -->

<link rel="stylesheet" href="../../Public/admin/plugins/jqvmap/jqvmap.min.css">

<!-- Theme style -->

<link rel="stylesheet" href="../../Public/admin/dist/css/adminlte.min.css">

<!-- overlayScrollbars -->

<link rel="stylesheet" href="../../Public/admin/plugins/overlayScrollbars/css/OverlayScrollbars.min.css">

<!-- Daterange picker -->

<link rel="stylesheet" href="../../Public/admin/plugins/daterangepicker/daterangepicker.css">

<!-- summernote -->

<link rel="stylesheet" href="../../Public/admin/plugins/summernote/summernote-bs4.css">

<!-- Google Font: Source Sans Pro -->

<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">

</head>

<div class="hold-transition sidebar-mini layout-fixed">

<div class="wrapper">

<!-- Navbar -->

<nav class="main-header navbar navbar-expand navbar-white navbar-light">

<!-- Left navbar links -->

<ul class="navbar-nav">

<li class="nav-item">

<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>

</li>

<li class="nav-item d-none d-sm-inline-block">

<a href="#" class="nav-link">Home</a>

</li>

<li class="nav-item d-none d-sm-inline-block">

<a href="#" class="nav-link">Contact</a>

</li>

</ul>

<!-- SEARCH FORM -->

<form class="form-inline ml-3">

<div class="input-group input-group-sm">

<input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">

<div class="input-group-append">

<button class="btn btn-navbar" type="submit">

<i class="fas fa-search"></i>

</button>

</div>

</div>

</form>

<!-- Right navbar links -->

<ul class="navbar-nav ml-auto">

<!-- Messages Dropdown Menu -->

<li class="nav-item dropdown">

<a class="nav-link" data-toggle="dropdown" href="#">

<i class="far fa-comments"></i>

<span class="badge badge-danger navbar-badge">3</span>

</a>

<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">

<a href="#" class="dropdown-item">

<!-- Message Start -->

<div class="media">

<img src="../../Public/admin/dist/img/user1-128x128.jpg" alt="User Avatar" class="img-size-50 mr-3 img-circle">

<div class="media-div">

<h3 class="dropdown-item-title">

Brad Diesel

<span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>

</h3>

<p class="text-sm">Call me whenever you can...</p>

<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>

</div>

</div>

<!-- Message End -->

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<!-- Message Start -->

<div class="media">

<img src="../../Public/admin/dist/img/user8-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">

<div class="media-div">

<h3 class="dropdown-item-title">

John Pierce

<span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>

</h3>

<p class="text-sm">I got your message bro</p>

<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>

</div>

</div>

<!-- Message End -->

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<!-- Message Start -->

<div class="media">

<img src="../../Public/admin/dist/img/user3-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">

<div class="media-div">

<h3 class="dropdown-item-title">

Nora Silvester

<span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span>

</h3>

<p class="text-sm">The subject goes here</p>

<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>

</div>

</div>

<!-- Message End -->

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item dropdown-footer">See All Messages</a>

</div>

</li>

<!-- Notifications Dropdown Menu -->

<li class="nav-item dropdown">

<a class="nav-link" data-toggle="dropdown" href="#">

<i class="far fa-bell"></i>

<span class="badge badge-warning navbar-badge">15</span>

</a>

<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">

<span class="dropdown-item dropdown-header">15 Notifications</span>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<i class="fas fa-envelope mr-2"></i> 4 new messages

<span class="float-right text-muted text-sm">3 mins</span>

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<i class="fas fa-users mr-2"></i> 8 friend requests

<span class="float-right text-muted text-sm">12 hours</span>

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<i class="fas fa-file mr-2"></i> 3 new reports

<span class="float-right text-muted text-sm">2 days</span>

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>

</div>

</li>

</ul>

</nav>

<!-- Main Sidebar Container -->

<aside class="main-sidebar sidebar-dark-primary elevation-4">

<!-- Brand Logo -->

<a href="index3." class="brand-link">

<img src="../../Public/admin/dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8">

<span class="brand-text font-weight-light">Admin</span>

</a>

<!-- Sidebar -->

<div class="sidebar">

<!-- Sidebar user panel (optional) -->

<div class="user-panel mt-3 pb-3 mb-3 d-flex">

<div class="image">

<img src="../../Public/admin/dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">

</div>

<div class="info">

<a href="#" class="d-block">Nguyễn Trọng Chính</a>

</div>

</div>

<!-- Sidebar Menu -->

<nav class="mt-2">

<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">

<!-- Add icons to the links using the .nav-icon class

with font-awesome or any other icon font library -->

<li class="nav-item has-treeview">

<a href="index.php" class="nav-link active">

<i class="nav-icon fas fa-tachometer-alt"></i>

<p>

Trang chủ

</p>

</a>

</li>

<li class="nav-item has-treeview">

<a href="#" class="nav-link">

<i class="nav-icon fas fa-copy"></i>

<p>

Chuyên mục

<i class="fas fa-angle-left right"></i>

<span class="badge badge-info right">6</span>

</p>

</a>

<ul class="nav nav-treeview">

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Thêm</p>

</a>

</li>

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Danh sách</p>

</a>

</li>

</ul>

</li>

<li class="nav-item has-treeview">

<a href="#" class="nav-link">

<i class="nav-icon fas fa-copy"></i>

<p>

Bài viết

<i class="fas fa-angle-left right"></i>

<span class="badge badge-info right">6</span>

</p>

</a>

<ul class="nav nav-treeview">

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Thêm</p>

</a>

</li>

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Danh sách</p>

</a>

</li>

</ul>

</li>

<li class="nav-item has-treeview">

<a href="#" class="nav-link">

<i class="nav-icon fas fa-copy"></i>

<p>

Thành viên

<i class="fas fa-angle-left right"></i>

<span class="badge badge-info right">6</span>

</p>

</a>

<ul class="nav nav-treeview">

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Thêm</p>

</a>

</li>

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Danh sách</p>

</a>

</li>

</ul>

</li>

</ul>

</nav>

<!-- /.sidebar-menu -->

</div>

<!-- /.sidebar -->

</aside>

File footer.php: Viết đoạn code sau vào file footer.php (đường dẫn: blog/View/admin/layouts/footer.php)  

<footer class="main-footer">

<strong>Copyright &copy; 2014-2019 <a href="#">BlogTinTuc</a>.</strong>

All rights reserved.

<div class="float-right d-none d-sm-inline-block">

<b>Version</b> 3.0.3-pre

</div>

</footer>

<!-- Control Sidebar -->

<aside class="control-sidebar control-sidebar-dark">

<!-- Control sidebar content goes here -->

</aside>

<!-- /.control-sidebar -->

</div>

<!-- ./wrapper -->

<script src="https://unpkg.com/[email protected]/dist/ionicons.js"></script>

<!-- jQuery -->

<script src="../../Public/admin/plugins/jquery/jquery.min.js"></script>

<!-- jQuery UI 1.11.4 -->

<script src="../../Public/admin/plugins/jquery-ui/jquery-ui.min.js"></script>

<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->

<script>

$.widget.bridge('uibutton', $.ui.button)

</script>

<!-- Bootstrap 4 -->

<script src="../../Public/admin/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>

<!-- ChartJS -->

<script src="../../Public/admin/plugins/chart.js/Chart.min.js"></script>

<!-- Sparkline -->

<script src="../../Public/admin/plugins/sparklines/sparkline.js"></script>

<!-- JQVMap -->

<script src="../../Public/admin/plugins/jqvmap/jquery.vmap.min.js"></script>

<script src="../../Public/admin/plugins/jqvmap/maps/jquery.vmap.usa.js"></script>

<!-- jQuery Knob Chart -->

<script src="../../Public/admin/plugins/jquery-knob/jquery.knob.min.js"></script>

<!-- daterangepicker -->

<script src="../../Public/admin/plugins/moment/moment.min.js"></script>

<script src="../../Public/admin/plugins/daterangepicker/daterangepicker.js"></script>

<!-- Tempusdominus Bootstrap 4 -->

<script src="../../Public/admin/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>

<!-- Summernote -->

<script src="../../Public/admin/plugins/summernote/summernote-bs4.min.js"></script>

<!-- overlayScrollbars -->

<script src="../../Public/admin/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>

<!-- AdminLTE App -->

<script src="../../Public/admin/dist/js/adminlte.js"></script>

<!-- AdminLTE dashboard demo (This is only for demo purposes) -->

<script src="../../Public/admin/dist/js/pages/dashboard.js"></script>

<!-- AdminLTE for demo purposes -->

<script src="../../Public/admin/dist/js/demo.js"></script>

</div>

</>

File home.php: copy và paste đoạn code sau vào file footer.php (đường dẫn: blog/View/admin/pages/home.php)    

<div class="content-wrapper" style="min-height: 365px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Trang chủ</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Home</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<div class="row">

<div class="col-lg-3 col-6">

<!-- small box -->

<div class="small-box bg-info">

<div class="inner">

<h3>150</h3>

<h4>CHUYÊN MỤC</h4>

</div>

<div class="icon">

<i class="ion ion-bag"></i>

</div>

<a href="#" class="small-box-footer">Chi tiết <i class="fas fa-arrow-circle-right"></i></a>

</div>

</div>

<!-- ./col -->

<div class="col-lg-3 col-6">

<!-- small box -->

<div class="small-box bg-success">

<div class="inner">

<h3>53<sup style="font-size: 20px">%</sup></h3>

<h4>BÀI VIẾT</h4>

</div>

<div class="icon">

<i class="ion ion-stats-bars"></i>

</div>

<a href="#" class="small-box-footer">Chi tiết <i class="fas fa-arrow-circle-right"></i></a>

</div>

</div>

<!-- ./col -->

<div class="col-lg-3 col-6">

<!-- small box -->

<div class="small-box bg-warning">

<div class="inner">

<h3>44</h3>

<h4 style="color: #fff">THÀNH VIÊN</h4>

</div>

<div class="icon">

<i class="ion ion-person-add"></i>

</div>

<a href="#" class="small-box-footer">Chi tiết <i class="fas fa-arrow-circle-right"></i></a>

</div>

</div>

<!-- ./col -->

<div class="col-lg-3 col-6">

<!-- small box -->

<div class="small-box bg-danger">

<div class="inner">

<h3>65</h3>

<h4>BÌNH LUẬN</h4>

</div>

<div class="icon">

<i class="ion ion-pie-graph"></i>

</div>

<a href="#" class="small-box-footer">Chi tiết <i class="fas fa-arrow-circle-right"></i></a>

</div>

</div>

<!-- ./col -->

</div>

</div>

</section>

</div>

File index.php: Viết đoạn code sau vào file index.php (đường dẫn: blog/View/admin/index.php)

<?php

require('layouts/header.php');

if (isset($_GET['controller'])) {

$controller = $_GET['controller'];

} else {

$controller = '';

}

switch ($controller) {

case 'test':

echo "trang test";

break;

default:

require('pages/home.php');

break;

}

require('layouts/footer.php');

Sau khi hoàn thành code cho các file, chúng ta chạy thử chương trình để xem kết quả theo đường dẫn: http://localhost/blog/View/admin/

Lập trình chức năng đăng ký

  • Chuẩn bị

Điều đầu tiên cần chuẩn bị cho trang Blog Tin Tức này đó chính là giao diện, giao diện đăng ký và đăng nhập chúng ta sẽ để cùng với trang chủ luôn vì vậy chúng ta sẽ xây dựng giao diện trang chủ trước.

Đây là giao diện đã chuẩn bị, các bạn có thể download tại đây. Sau khi tải về, các bạn giải nén được một thư mục blog gồm các file như trong ảnh dưới đây.

  • Xây dựng giao diện trang chủ

Sau khi hoàn thành xong bước chuẩn bị ở phần 1, chúng ta bắt đầu đi xây dựng giao diện trang chủ.

Trước tiên cần tiếp tục tạo thêm cho mình các thư mục và file như trong ảnh dưới đây:

Sau khi tạo xong chúng ta tiến hành thêm các đoạn mã code vào. Trước tiên chúng ta copy các thư mục (cssfontsimgjsvendor) và file style.css từ thư mục blog chúng ta đã tải và giải nén ở mục 1 vào thư mục Public/client trong project của chúng ta.

Tiếp theo chúng ta tiến hành format lại file style.css. Copy toàn bộ code từ file style.css và paste vào (https://www.cleancss.com/css-beautify/) để format code. Sau khi format xong paste lại vào và sửa ở dòng 2534 và 2536 như sau:

Bước tiếp theo chúng ta viết code cho file index.php (blog/index.php), header.php (blog/View/client/layouts/header.php), footer.php (blog/View/client/layouts/footer.php).

Chèn đoạn sau vào file header.php:

<!doctype >

< class="no-js" lang="">

<!-- Mirrored from www.radiustheme.com/demo//newsedge/newsedge/index. by HTTrack Website Copier/3.x [XR&CO'2014], Thu, 13 Feb 2020 08:41:57 GMT -->

<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/;charset=UTF-8" /><!-- /Added by HTTrack -->

<head>

<meta charset="utf-8">

<meta http-equiv="x-ua-compatible" content="ie=edge">

<title>NewsEdge | Home 1</title>

<meta name="description" content="">

<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Favicon -->

<link rel="shortcut icon" type="image/x-icon" href="Public/client/img/favicon.png">

<!-- Normalize CSS -->

<link rel="stylesheet" href="Public/client/css/normalize.css">

<!-- Main CSS -->

<link rel="stylesheet" href="Public/client/css/main.css">

<!-- Bootstrap CSS -->

<link rel="stylesheet" href="Public/client/css/bootstrap.min.css">

<!-- Animate CSS -->

<link rel="stylesheet" href="Public/client/css/animate.min.css">

<!-- Font-awesome CSS-->

<link rel="stylesheet" href="Public/client/css/font-awesome.min.css">

<!-- Owl Caousel CSS -->

<link rel="stylesheet" href="Public/client/vendor/OwlCarousel/owl.carousel.min.css">

<link rel="stylesheet" href="Public/client/vendor/OwlCarousel/owl.theme.default.min.css">

<!-- Main Menu CSS -->

<link rel="stylesheet" href="Public/client/css/meanmenu.min.css">

<!-- Magnific CSS -->

<link rel="stylesheet" type="none" href="Public/client/css/magnific-popup.css">

<!-- Switch Style CSS -->

<link rel="stylesheet" href="Public/client/css/hover-min.css">

<!-- Custom CSS -->

<link rel="stylesheet" href="Public/client/style.css">

<!-- For IE -->

<link rel="stylesheet" type="none" href="Public/client/css/ie-only.css" />

<!-- Modernizr Js -->

<script src="Public/client/js/modernizr-2.8.3.min.js"></script>

</head>

<div>

<div id="preloader"></div>

<!-- Preloader End Here -->

<div id="wrapper" class="wrapper">

<!-- Header Area Start Here -->

<header>

<div id="header-layout1" class="header-style1">

<div class="main-menu-area bg-primarytextcolor header-menu-fixed" id="sticker">

<div class="container">

<div class="row no-gutters d-flex align-items-center">

<div class="col-lg-2 d-none d-lg-block">

<div class="logo-area">

<a href="index.">

<img src="Public/client/img/logo.png" alt="logo" class="img-fluid">

</a>

</div>

</div>

<div class="col-xl-7 col-lg-6 position-static min-height-none">

<div class="ne-main-menu">

<nav id="dropdown">

<ul>

<li class="active">

<a href="#">Home</a>

<ul class="ne-dropdown-menu">

<li class="active">

<a href="index.">Home 1</a>

</li>

<li>

<a href="index2.">Home 2</a>

</li>

<li>

<a href="index3.">Home 3</a>

</li>

<li>

<a href="index4.">Home 4</a>

</li>

<li>

<a href="index5.">Home 5</a>

</li>

<li>

<a href="index6.">Home 6</a>

</li>

<li>

<a href="index7.">Home 7</a>

</li>

</ul>

</li>

<li>

<a href="#">Post</a>

<ul class="ne-dropdown-menu">

<li>

<a href="post-style-1.">Post Style 1</a>

</li>

<li>

<a href="post-style-2.">Post Style 2</a>

</li>

<li>

<a href="post-style-3.">Post Style 3</a>

</li>

<li>

<a href="post-style-4.">Post Style 4</a>

</li>

<li>

<a href="single-news-1.">News Details 1</a>

</li>

<li>

<a href="single-news-2.">News Details 2</a>

</li>

<li>

<a href="single-news-3.">News Details 3</a>

</li>

</ul>

</li>

<li>

<a href="#">Pages</a>

<ul class="ne-dropdown-menu">

<li>

<a href="author-post.">Author Post Page</a>

</li>

<li>

<a href="archive.">Archive Page</a>

</li>

<li>

<a href="gallery-style-1.">Gallery Style 1</a>

</li>

<li>

<a href="gallery-style-2.">Gallery Style 2</a>

</li>

<li>

<a href="404.">404 Error Page</a>

</li>

<li>

<a href="contact.">Contact Page</a>

</li>

</ul>

</li>

<li>

<a href="post-style-1.">Politics</a>

</li>

<li>

<a href="post-style-2.">Business</a>

</li>

<li>

<a href="post-style-3.">Sports</a>

</li>

<li>

<a href="post-style-4.">Fashion</a>

</li>

</ul>

</nav>

</div>

</div>

<div class="col-xl-3 col-lg-4 col-md-12 text-right position-static">

<div class="header-action-item">

<ul>

<li>

<form id="top-search-form" class="header-search-light">

<input type="text" class="search-input" placeholder="Search...." required="" style="display: none;">

<button class="search-button">

<i class="fa fa-search" aria-hidden="true"></i>

</button>

</form>

</li>

<li>

<button type="button" class="login-btn" data-toggle="modal" data-target="#signup">

<i class="fa fa-user" aria-hidden="true"></i>Sign up

</button>

</li>

<li>

<button type="button" class="login-btn" data-toggle="modal" data-target="#myModal">

<i class="fa fa-user" aria-hidden="true"></i>Sign in

</button>

</li>

<li>

<div id="side-menu-trigger" class="offcanvas-menu-btn">

<a href="#" class="menu-bar">

<span></span>

<span></span>

<span></span>

</a>

<a href="#" class="menu-times close">

<span></span>

<span></span>

</a>

</div>

</li>

</ul>

</div>

</div>

</div>

</div>

</div>

</div>

</header>

<!-- Header Area End Here -->

<!-- News Feed Area Start Here -->

<section class="bg-accent border-bottom add-top-margin">

<div class="container">

<div class="row no-gutters d-flex align-items-center">

<div class="col-lg-2 col-md-3 col-sm-4 col-6">

<div class="topic-box topic-box-margin">Top Stories</div>

</div>

<div class="col-lg-10 col-md-9 col-sm-8 col-6">

<div class="feeding-text-dark">

<ol id="sample" class="ticker">

<li>

<a href="#">McDonell Kanye West highlights difficulties for celebritiesComplimentary decor and

design advicewith Summit Park homes</a>

</li>

<li>

<a href="#">Magnificent Image Of The New Hoover Dam Bridge Taking Shape</a>

</li>

<li>

<a href="#">If Obama Had Governed Like This in 2017 He'd Be the Transformational.</a>

</li>

</ol>

</div>

</div>

</div>

</div>

</section>

<!-- News Feed Area End Here -->

<!-- News Info List Area Start Here -->

<section class="bg-div">

<div class="container">

<ul class="news-info-list text-center--md">

<li>

<i class="fa fa-map-marker" aria-hidden="true"></i>Australia</li>

<li>

<i class="fa fa-calendar" aria-hidden="true"></i><span id="current_date"></span></li>

<li>

<i class="fa fa-clock-o" aria-hidden="true"></i>Last Update 11.30 am</li>

<li>

<i class="fa fa-cloud" aria-hidden="true"></i>29&#8451; Sydney, Australia</li>

</ul>

</div>

</section>

<!-- Đăng nhập-->

<div class="modal fade" id="myModal" role="dialog">

<div class="modal-dialog">

<div class="modal-content">

<div class="modal-header">

<button type="button" class="close" data-dismiss="modal">&times;</button>

<div class="title-login-form">Đăng nhập</div>

</div>

<div class="modal-div">

<div class="login-form">

<form>

<label>Tên đăng nhập *</label>

<input name="username" type="text" placeholder="Tên đăng nhập" />

<label>Mật khẩu *</label>

<input name="password" type="password" placeholder="Mật khẩu" />

<div class="checkbox checkbox-primary">

<input id="checkbox" type="checkbox" checked>

<label for="checkbox">Nhớ mật khẩu</label>

</div>

<button type="submit" value="Login">Đăng nhập</button>

<button class="form-cancel" type="submit" value="">Hủy</button>

<label class="lost-password">

<a href="#">Quên mật khẩu?</a>

</label>

</form>

</div>

</div>

</div>

</div>

</div>

<!-- Đăng nhâp End-->

<!-- Đăng ký-->

<div class="modal fade" id="signup" role="dialog">

<div class="modal-dialog">

<div class="modal-content">

<div class="modal-header">

<button type="button" class="close" data-dismiss="modal">&times;</button>

<div class="title-login-form">Đăng ký</div>

</div>

<div class="modal-div">

<div class="login-form">

<form method="post">

<label>Tên đăng nhập *</label>

<input type="text" name="username" placeholder="Tên đăng nhập" />

<label>Mật khẩu *</label>

<input type="password" name="password" placeholder="Mật khẩu" />

<label>Họ và tên *</label>

<input type="text" name="full_name" placeholder="Họ tên" />

<button type="submit" value="Login" name="signup">Đăng ký</button>

<button class="form-cancel" type="submit" value="">Hủy</button>

</form>

</div>

</div>

</div>

</div>

</div>

<!-- Đăng ký End-->

Chèn đoạn sau vào file footer.php:

<footer>

<div class="footer-area-top">

<div class="container">

<div class="row">

<div class="col-lg-4 col-md-6 col-sm-12">

<div class="footer-box">

<h2 class="title-bold-light title-bar-left text-uppercase">Most Viewed Posts</h2>

<ul class="most-view-post">

<li>

<div class="media">

<a href="post-style-1.">

<img src="Public/client/img/footer/post1.jpg" alt="post" class="img-fluid">

</a>

<div class="media-div">

<h3 class="title-medium-light size-md mb-10">

<a href="#">Basketball Stars Face Off itim ate Playoff Beard Battle</a>

</h3>

<div class="post-date-light">

<ul>

<li>

<span>

<i class="fa fa-calendar" aria-hidden="true"></i>

</span>November 11, 2017</li>

</ul>

</div>

</div>

</div>

</li>

<li>

<div class="media">

<a href="post-style-2.">

<img src="Public/client/img/footer/post2.jpg" alt="post" class="img-fluid">

</a>

<div class="media-div">

<h3 class="title-medium-light size-md mb-10">

<a href="#">Basketball Stars Face Off in ate Playoff Beard Battle</a>

</h3>

<div class="post-date-light">

<ul>

<li>

<span>

<i class="fa fa-calendar" aria-hidden="true"></i>

</span>August 22, 2017</li>

</ul>

</div>

</div>

</div>

</li>

<li>

<div class="media">

<a href="post-style-3.">

<img src="Public/client/img/footer/post3.jpg" alt="post" class="img-fluid">

</a>

<div class="media-div">

<h3 class="title-medium-light size-md mb-10">

<a href="#">Basketball Stars Face tim ate Playoff Battle</a>

</h3>

<div class="post-date-light">

<ul>

<li>

<span>

<i class="fa fa-calendar" aria-hidden="true"></i>

</span>March 31, 2017</li>

</ul>

</div>

</div>

</div>

</li>

</ul>

</div>

</div>

<div class="col-xl-4 col-lg-3 col-md-6 col-sm-12">

<div class="footer-box">

<h2 class="title-bold-light title-bar-left text-uppercase">Popular Categories</h2>

<ul class="popular-categories">

<li>

<a href="#">Gadgets

<span>15</span>

</a>

</li>

<li>

<a href="#">Architecture

<span>10</span>

</a>

</li>

<li>

<a href="#">New look 2017

<span>14</span>

</a>

</li>

<li>

<a href="#">Reviews

<span>13</span>

</a>

</li>

<li>

<a href="#">Mobile and Phones

<span>19</span>

</a>

</li>

<li>

<a href="#">Recipes

<span>26</span>

</a>

</li>

<li>

<a href="#">Decorating

<span>21</span>

</a>

</li>

<li>

<a href="#">IStreet fashion

<span>09</span>

</a>

</li>

</ul>

</div>

</div>

<div class="col-xl-4 col-lg-5 col-md-12 col-sm-12">

<div class="footer-box">

<h2 class="title-bold-light title-bar-left text-uppercase">Post Gallery</h2>

<ul class="post-gallery shine-hover ">

<li>

<a href="gallery-style1.">

<figure>

<img src="Public/client/img/footer/post4.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style2.">

<figure>

<img src="Public/client/img/footer/post5.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style1.">

<figure>

<img src="Public/client/img/footer/post6.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style2.">

<figure>

<img src="Public/client/img/footer/post7.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style1.">

<figure>

<img src="Public/client/img/footer/post8.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style2.">

<figure>

<img src="Public/client/img/footer/post9.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style1.">

<figure>

<img src="Public/client/img/footer/post10.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style2.">

<figure>

<img src="Public/client/img/footer/post11.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

<li>

<a href="gallery-style1.">

<figure>

<img src="Public/client/img/footer/post12.jpg" alt="post" class="img-fluid">

</figure>

</a>

</li>

</ul>

</div>

</div>

</div>

</div>

</div>

<div class="footer-area-bottom">

<div class="container">

<div class="row">

<div class="col-12 text-center">

<a href="index." class="footer-logo img-fluid">

<img src="Public/client/img/logo.png" alt="logo" class="img-fluid">

</a>

<ul class="footer-social">

<li>

<a href="#" title="facebook">

<i class="fa fa-facebook" aria-hidden="true"></i>

</a>

</li>

<li>

<a href="#" title="twitter">

<i class="fa fa-twitter" aria-hidden="true"></i>

</a>

</li>

<li>

<a href="#" title="google-plus">

<i class="fa fa-google-plus" aria-hidden="true"></i>

</a>

</li>

<li>

<a href="#" title="linkedin">

<i class="fa fa-linkedin" aria-hidden="true"></i>

</a>

</li>

<li>

<a href="#" title="pinterest">

<i class="fa fa-pinterest" aria-hidden="true"></i>

</a>

</li>

<li>

<a href="#" title="rss">

<i class="fa fa-rss" aria-hidden="true"></i>

</a>

</li>

<li>

<a href="#" title="vimeo">

<i class="fa fa-vimeo" aria-hidden="true"></i>

</a>

</li>

</ul>

<p>© 2017 newsedge Designed by RadiusTheme. All Rights Reserved</p>

</div>

</div>

</div>

</div>

</footer>

<!-- Footer Area End Here -->

<!-- Offcanvas Menu Start -->

<div id="offcanvas-div-wrapper" class="offcanvas-div-wrapper">

<div id="offcanvas-nav-close" class="offcanvas-nav-close offcanvas-menu-btn">

<a href="#" class="menu-times re-point">

<span></span>

<span></span>

</a>

</div>

<div class="offcanvas-main-div">

<ul id="accordion" class="offcanvas-nav panel-group">

<li class="panel panel-default">

<div class="panel-heading">

<a aria-expanded="false" class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseOne">

<i class="fa fa-home" aria-hidden="true"></i>Home Pages</a>

</div>

<div aria-expanded="false" id="collapseOne" role="tabpanel" class="panel-collapse collapse">

<div class="panel-div">

<ul class="offcanvas-sub-nav">

<li>

<a href="index.">Home 1</a>

</li>

<li>

<a href="index2.">Home 2</a>

</li>

<li>

<a href="index3.">Home 3</a>

</li>

<li>

<a href="index4.">Home 4</a>

</li>

<li>

<a href="index5.">Home 5</a>

</li>

<li>

<a href="index6.">Home 6</a>

</li>

<li>

<a href="index7.">Home 7</a>

</li>

</ul>

</div>

</div>

</li>

<li>

<a href="author-post.">

<i class="fa fa-user" aria-hidden="true"></i>Author Post Page</a>

</li>

<li class="panel panel-default">

<div class="panel-heading">

<a aria-expanded="false" class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">

<i class="fa fa-file-text" aria-hidden="true"></i>Post Pages</a>

</div>

<div aria-expanded="false" id="collapseTwo" role="tabpanel" class="panel-collapse collapse">

<div class="panel-div">

<ul class="offcanvas-sub-nav">

<li>

<a href="post-style-1.">Post Style 1</a>

</li>

<li>

<a href="post-style-2.">Post Style 2</a>

</li>

<li>

<a href="post-style-3.">Post Style 3</a>

</li>

<li>

<a href="post-style-4.">Post Style 4</a>

</li>

</ul>

</div>

</div>

</li>

<li class="panel panel-default">

<div class="panel-heading">

<a aria-expanded="false" class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseThree">

<i class="fa fa-info-circle" aria-hidden="true"></i>News Details Pages</a>

</div>

<div aria-expanded="false" id="collapseThree" role="tabpanel" class="panel-collapse collapse">

<div class="panel-div">

<ul class="offcanvas-sub-nav">

<li>

<a href="single-news-1.">News Details 1</a>

</li>

<li>

<a href="single-news-2.">News Details 2</a>

</li>

<li>

<a href="single-news-3.">News Details 3</a>

</li>

</ul>

</div>

</div>

</li>

<li>

<a href="archive.">

<i class="fa fa-archive" aria-hidden="true"></i>Archive Page</a>

</li>

<li class="panel panel-default">

<div class="panel-heading">

<a aria-expanded="false" class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseFour">

<i class="fa fa-picture-o" aria-hidden="true"></i>Gallery Pages</a>

</div>

<div aria-expanded="false" id="collapseFour" role="tabpanel" class="panel-collapse collapse">

<div class="panel-div">

<ul class="offcanvas-sub-nav">

<li>

<a href="gallery-style-1.">Gallery Style 1</a>

</li>

<li>

<a href="gallery-style-2.">Gallery Style 2</a>

</li>

</ul>

</div>

</div>

</li>

<li>

<a href="404.">

<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>404 Error Page</a>

</li>

<li>

<a href="contact.">

<i class="fa fa-phone" aria-hidden="true"></i>Contact Page</a>

</li>

</ul>

</div>

</div>

<!-- Offcanvas Menu End -->

</div>

<!-- Wrapper End -->

<!-- jquery-->

<script src="Public/client/js/jquery-2.2.4.min.js" type="text/javascript"></script>

<!-- Plugins js -->

<script src="Public/client/js/plugins.js" type="text/javascript"></script>

<!-- Popper js -->

<script src="Public/client/js/popper.js" type="text/javascript"></script>

<!-- Bootstrap js -->

<script src="Public/client/js/bootstrap.min.js" type="text/javascript"></script>

<!-- WOW JS -->

<script src="Public/client/js/wow.min.js"></script>

<!-- Owl Cauosel JS -->

<script src="Public/client/vendor/OwlCarousel/owl.carousel.min.js" type="text/javascript"></script>

<!-- Meanmenu Js -->

<script src="Public/client/js/jquery.meanmenu.min.js" type="text/javascript"></script>

<!-- Srollup js -->

<script src="Public/client/js/jquery.scrollUp.min.js" type="text/javascript"></script>

<!-- jquery.counterup js -->

<script src="Public/client/js/jquery.counterup.min.js"></script>

<script src="Public/client/js/waypoints.min.js"></script>

<!-- Isotope js -->

<script src="Public/client/js/isotope.pkgd.min.js" type="text/javascript"></script>

<!-- Magnific Popup -->

<script src="Public/client/js/jquery.magnific-popup.min.js"></script>

<!-- Ticker Js -->

<script src="Public/client/js/ticker.js" type="text/javascript"></script>

<!-- Custom Js -->

<script src="Public/client/js/main.js" type="text/javascript"></script>

</div>

</>

Sửa file index.php thành:

<?php

require 'Model/Database.php';

$db = new Database();

require 'View/client/layouts/header.php'; /*giao diện header*/

if (isset($_GET['controller'])) {

require '../../Route/admin/web.php'; /*xử lý các request trong Route/web.php*/

} else {

require 'View/client/pages/home.php'; /*require giao diện trang chủ*/

}

require 'View/client/layouts/footer.php'; /*giao diện footer*/

$db->closeDatabase();

Giải thích: 

  1. Kiểm tra nếu tồn tại $_GET['controller'] thì ta require Route/web.php - xử lý toàn bộ request trên thanh địa chỉ url, nếu không tồn tại $_GET['controller'] => show giao diện trang chủ.  

Tạo file Route/admin/web.php và chèn đoạn code sau:

<?php

$controller = $_GET['controller'];

require('../../Controller/admin/' . $controller . '.php'); /*require controller tương ứng*/

$controller = ucfirst($controller); /*chuyển đổi chữ cái đầu tiên của chuỗi thành chữ hoa */

$request = new $controller; /*khởi tạo một class controller tương ứng với biến $controller*/

Tiếp tục ta tạo thêm thư mục Route và file web.php

Chèn đoạn sau vào file web.php:

<?php

$controller = $_GET['controller'];

require('Controller/' . $controller . '.php'); /*require controller tương ứng*/

$controller = ucfirst($controller); /*chuyển đổi chữ cái đầu tiên của chuỗi thành chữ hoa */

$request = new $controller; /*khởi tạo một class controller tương ứng với biến $controller*/

Giải thích:

  1. Trong file web.php này sẽ nhận request từ thanh địa chỉ url và xử lý trong các controller tương ứng.

  2. Chú ý: đặt tên class trong Controller giống với giá trị $_GET['controller'] và viết hoa chữ cái đầu. 

  3. Ví dụ: $_GET['controller'] = 'category', class sẽ đặt tên là Category.

Cuối cùng tiến hành chạy thử chương trình theo đường dẫn: http://localhost/blog/ được kết quả như hình:

3) Làm chức năng đăng ký

Do form đăng ký để ở header vì vậy ta sẽ require file header.php trong controller.

Thay đổi dòng code:

require 'View/client/layouts/header.php'; /*giao diện header*/

Thành:

require('Controller/client/header.php');

Tạo thêm thư mục client nằm trong thư mục Controller. Trong thư mục client tạo file header.php.

Tiếp theo bạn viết hàm đăng ký và kiểm tra trùng username trong file Model/client/UserModel.php:

<?php

class UserModel extends Database{

protected $db;

public function __construct()

{

$this->db = new Database();

$this->db->connect();

}

public function signup($username, $password, $fullName)

{

$sql = "INSERT INTO users (username, password, full_name)

VALUES ('$username', '$password', '$fullName')";

$this->db->conn->query($sql);

}

public function checkExists($username) {

$sql = "SELECT * FROM users WHERE username = '$username'";

$result = $this->db->conn->query($sql);

return $result;

}

}

Sau khi viết hàm signup xong, chúng ta bắt đầu viết code cho file Controller/client/header.php:

<?php

class Header {

public function __construct()

{

require('Model/client/UserModel.php');

$userModel = new UserModel();

$error = $this->signUp($userModel);

require('View/client/layouts/header.php');

}

public function signUp($userModel) {

$username = $password = $fullName = NULL;

$error = array();

$error['username'] = $error['password'] = $error['full_name'] = $error['username_exist'] = NULL;

if (isset($_POST['signup'])) {

if (empty($_POST['username'])) {

$error['username'] = '* Cần điền tên đăng nhập';

} else {

$username = $_POST['username'];

}

if (empty($_POST['password'])) {

$error['password'] = '* Cần điền mật khẩu';

} else {

$password = md5(md5($_POST['password']));

}

if (empty($_POST['full_name'])) {

$error['full_name'] = '* Cần điền họ tên';

} else {

$fullName = $_POST['full_name'];

}

if ($username && $password && $fullName) {

$check = $userModel->checkExists($username);

if ($check->num_rows > 0) {

$error['username_exist'] = '* Tên đăng nhập đã bị trùng';

} else {

$userModel->signup($username, $password, $fullName);

echo "<script>alert('đăng ký thành công')</script>";

}

}

}

return $error;

}

}

$header = new Header();

Cuối cùng chúng ta hiển thị lỗi khi không nhập đầy đủ thông tin, chèn đoạn code sau vào file

View/client/layouts/header.php (sau dòng <div id="preloader"></div>).

<?php

if (isset($error['username'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?php echo $error['username']?>

</div>

<?php } else if (isset($error['password'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?=$error['password']?>

</div>

<?php } else if (isset($error['full_name'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?=$error['full_name']?>

</div>

<?php } else if (isset($error['username_exist'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?=$error['username_exist']?>

</div>

<?php }

?>

Lập trình chức năng đăng nhập cho người dùng

Trong phần thiết kế cơ sở dữ liệu thấy ở bảng users có trường level, trường này có chức năng phân biệt được đâu là người dùng và đâu là quản trị viên (admin). Trong Project này chúng ta sẽ chỉ phần quyền ở 2 cấp độ: người dùng (level = 0) và quản trị viên (level = 1).

Trước khi xây dựng chức năng đăng nhập chúng ta sẽ viết viết lại file View/admin/index.php để kiểm tra xem level của người đăng nhập có phải là quản trị viên hay không, nếu không phải thì chuyển hướng người dùng về trang chủ.

Tạo file Config/config.php:

Tiến hành khai báo hằng số cho file config.php:

<?php

define('admin', 1); // quyền admin

define('client', 0); // quyền người dùng thông thường

Trong file config.php chúng ta sẽ khai báo những hằng số cố định ít thay đổi để tiện cho việc bảo trì sau này.

Tiền hành viết câu lệnh truy vấn sql kiểm tra tên đăng nhập và mật khẩu trong file Model/client/UserModel.php:

public function login($username, $password)

{

$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

$result = $this->db->conn->query($sql);

return $result;

}

Tiếp theo tiến hành viết hàm đăng nhập trong file Controller/client/header.php:

public function login($userModel)

{

$username = $password = $fullName = NULL;

$error = array();

$error['username'] = $error['password'] = NULL;

if (!empty($_POST['login'])) {

if (empty($_POST['username'])) {

$error['username'] = '* Cần điền tên đăng nhập';

} else {

$username = $_POST['username'];

}

if (empty($_POST['password'])) {

$error['password'] = '* Cần điền mật khẩu';

} else {

$password = md5(md5($_POST['password']));

}

if ($username && $password) {

$result = $userModel->login($username, $password);

$check = $result->num_rows; /*đếm số dòng trong database*/

/**

* Nếu số dòng trong database > 0 => lưu session + lấy dữ liệu + chuyển hướng

* Ngược lại thông báo alert bằng script

* @var array

*/

if ($check > 0) {

$data = $result->fetch_array(); /*lấy dữ liệu tương ứng với username và password nhập*/

$_SESSION['user'] = $data; /*lưu session*/

header('Location: ./');

} else {

echo "<script>alert('Sai mật khẩu hoặc tên đăng nhập')</script>";

}

}

}

return $error;

}

File Controller/client/header.php hoàn chỉnh:

<?php

class Header {

public function __construct()

{

require_once('Model/client/UserModel.php');

$userModel = new UserModel();

$error = $this->signUp($userModel);

$errorLogin = $this->login($userModel);

require('View/client/layouts/header.php');

}

public function signUp($userModel) {

$username = $password = $fullName = NULL;

$error = array();

$error['username'] = $error['password'] = $error['full_name'] = $error['username_exist'] = NULL;

if (isset($_POST['signup'])) {

if (empty($_POST['username'])) {

$error['username'] = '* Cần điền tên đăng nhập';

} else {

$username = $_POST['username'];

}

if (empty($_POST['password'])) {

$error['password'] = '* Cần điền mật khẩu';

} else {

$password = md5(md5($_POST['password']));

}

if (empty($_POST['full_name'])) {

$error['full_name'] = '* Cần điền họ tên';

} else {

$fullName = $_POST['full_name'];

}

if ($username && $password && $fullName) {

$check = $userModel->checkExists($username);

if ($check->num_rows > 0) {

$error['username_exist'] = '* Tên đăng nhập đã bị trùng';

} else {

$userModel->signup($username, $password, $fullName);

echo "<script>alert('đăng ký thành công')</script>";

}

}

}

return $error;

}

public function login($userModel)

{

$username = $password = $fullName = NULL;

$error = array();

$error['username'] = $error['password'] = NULL;

if (!empty($_POST['login'])) {

if (empty($_POST['username'])) {

$error['username'] = '* Cần điền tên đăng nhập';

} else {

$username = $_POST['username'];

}

if (empty($_POST['password'])) {

$error['password'] = '* Cần điền mật khẩu';

} else {

$password = md5(md5($_POST['password']));

}

if ($username && $password) {

$result = $userModel->login($username, $password);

$check = $result->num_rows; /*đếm số dòng trong database*/

/**

* Nếu số dòng trong database > 0 => lưu session + lấy dữ liệu + chuyển hướng

* Ngược lại thông báo alert bằng script

* @var array

*/

if ($check > 0) {

$data = $result->fetch_array(); /*lấy dữ liệu tương ứng với username và password nhập*/

$_SESSION['user'] = $data; /*lưu session*/

header('Location: ./');

} else {

echo "<script>alert('Sai mật khẩu hoặc tên đăng nhập')</script>";

}

}

}

return $error;

}

}

$header = new Header();

Hiển thị tên đăng nhập sau khi đăng nhập thành công trong file View/client/layouts/header.php:

<?php

if (!empty($_SESSION['user'])) {?>

<li>

<button type="button" class="login-btn">

<i class="fa fa-user" aria-hidden="true"></i>

<?=$_SESSION['user']['username']?>

</button>

</li>

<li>

<button type="button" class="login-btn">

<i class="fa fa-user" aria-hidden="true"></i>

<a href="?controller=logout" style="color: #fff">

Logout

</a>

</button>

</li>

<?php } else {?>

<li>

<button type="button" class="login-btn" data-toggle="modal" data-target="#signup">

<i class="fa fa-user" aria-hidden="true"></i>

Signup

</button>

</li>

<li>

<button type="button" class="login-btn" data-toggle="modal" data-target="#myModal">

<i class="fa fa-user" aria-hidden="true"></i>Login

</button>

</li>

<?php }

?>

  File View/client/layouts/header.php hoàn chỉnh:  

<!doctype >

< class="no-js" lang="">

<!-- Mirrored from www.radiustheme.com/demo//newsedge/newsedge/index. by HTTrack Website Copier/3.x [XR&CO'2014], Thu, 13 Feb 2020 08:41:57 GMT -->

<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/;charset=UTF-8" /><!-- /Added by HTTrack -->

<head>

<meta charset="utf-8">

<meta http-equiv="x-ua-compatible" content="ie=edge">

<title>NewsEdge | Home 1</title>

<meta name="description" content="">

<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Favicon -->

<link rel="shortcut icon" type="image/x-icon" href="Public/client/img/favicon.png">

<!-- Normalize CSS -->

<link rel="stylesheet" href="Public/client/css/normalize.css">

<!-- Main CSS -->

<link rel="stylesheet" href="Public/client/css/main.css">

<!-- Bootstrap CSS -->

<link rel="stylesheet" href="Public/client/css/bootstrap.min.css">

<!-- Animate CSS -->

<link rel="stylesheet" href="Public/client/css/animate.min.css">

<!-- Font-awesome CSS-->

<link rel="stylesheet" href="Public/client/css/font-awesome.min.css">

<!-- Owl Caousel CSS -->

<link rel="stylesheet" href="Public/client/vendor/OwlCarousel/owl.carousel.min.css">

<link rel="stylesheet" href="Public/client/vendor/OwlCarousel/owl.theme.default.min.css">

<!-- Main Menu CSS -->

<link rel="stylesheet" href="Public/client/css/meanmenu.min.css">

<!-- Magnific CSS -->

<link rel="stylesheet" type="none" href="Public/client/css/magnific-popup.css">

<!-- Switch Style CSS -->

<link rel="stylesheet" href="Public/client/css/hover-min.css">

<!-- Custom CSS -->

<link rel="stylesheet" href="Public/client/style.css">

<!-- For IE -->

<link rel="stylesheet" type="none" href="Public/client/css/ie-only.css" />

<!-- Modernizr Js -->

<script src="Public/client/js/modernizr-2.8.3.min.js"></script>

</head>

<div>

<div id="preloader"></div>

<?php

if (isset($error['username'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?php echo $error['username']?>

</div>

<?php } else if (isset($error['password'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?=$error['password']?>

</div>

<?php } else if (isset($error['full_name'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?=$error['full_name']?>

</div>

<?php } else if (isset($error['username_exist'])) {?>

<div class="alert alert-danger" style="top: 155px; position: absolute; z-index: 5; width: auto; right: 0px;" role="alert">

<?=$error['username_exist']?>

</div>

<?php }

?>

<!-- Preloader End Here -->

<div id="wrapper" class="wrapper">

<!-- Header Area Start Here -->

<header>

<div id="header-layout1" class="header-style1">

<div class="main-menu-area bg-primarytextcolor header-menu-fixed" id="sticker">

<div class="container">

<div class="row no-gutters d-flex align-items-center">

<div class="col-lg-2 d-none d-lg-block">

<div class="logo-area">

<a href="index.">

<img src="Public/client/img/logo.png" alt="logo" class="img-fluid">

</a>

</div>

</div>

<div class="col-xl-7 col-lg-6 position-static min-height-none">

<div class="ne-main-menu">

<nav id="dropdown">

<ul>

<li class="active">

<a href="#">Home</a>

<ul class="ne-dropdown-menu">

<li class="active">

<a href="index.">Home 1</a>

</li>

<li>

<a href="index2.">Home 2</a>

</li>

<li>

<a href="index3.">Home 3</a>

</li>

<li>

<a href="index4.">Home 4</a>

</li>

<li>

<a href="index5.">Home 5</a>

</li>

<li>

<a href="index6.">Home 6</a>

</li>

<li>

<a href="index7.">Home 7</a>

</li>

</ul>

</li>

<li>

<a href="#">Post</a>

<ul class="ne-dropdown-menu">

<li>

<a href="post-style-1.">Post Style 1</a>

</li>

<li>

<a href="post-style-2.">Post Style 2</a>

</li>

<li>

<a href="post-style-3.">Post Style 3</a>

</li>

<li>

<a href="post-style-4.">Post Style 4</a>

</li>

<li>

<a href="single-news-1.">News Details 1</a>

</li>

<li>

<a href="single-news-2.">News Details 2</a>

</li>

<li>

<a href="single-news-3.">News Details 3</a>

</li>

</ul>

</li>

<li>

<a href="#">Pages</a>

<ul class="ne-dropdown-menu">

<li>

<a href="author-post.">Author Post Page</a>

</li>

<li>

<a href="archive.">Archive Page</a>

</li>

<li>

<a href="gallery-style-1.">Gallery Style 1</a>

</li>

<li>

<a href="gallery-style-2.">Gallery Style 2</a>

</li>

<li>

<a href="404.">404 Error Page</a>

</li>

<li>

<a href="contact.">Contact Page</a>

</li>

</ul>

</li>

<li>

<a href="post-style-1.">Politics</a>

</li>

<li>

<a href="post-style-2.">Business</a>

</li>

<li>

<a href="post-style-3.">Sports</a>

</li>

<li>

<a href="post-style-4.">Fashion</a>

</li>

</ul>

</nav>

</div>

</div>

<div class="col-xl-3 col-lg-4 col-md-12 text-right position-static">

<div class="header-action-item">

<ul>

<li>

<form id="top-search-form" class="header-search-light">

<input type="text" class="search-input" placeholder="Search...." required="" style="display: none;">

<button class="search-button">

<i class="fa fa-search" aria-hidden="true"></i>

</button>

</form>

</li>

<?php

if (!empty($_SESSION['user'])) {?>

<li>

<button type="button" class="login-btn">

<i class="fa fa-user" aria-hidden="true"></i>

<?=$_SESSION['user']['username']?>

</button>

</li>

<li>

<button type="button" class="login-btn">

<i class="fa fa-user" aria-hidden="true"></i>

<a href="?controller=logout" style="color: #fff">

Logout

</a>

</button>

</li>

<?php } else {?>

<li>

<button type="button" class="login-btn" data-toggle="modal" data-target="#signup">

<i class="fa fa-user" aria-hidden="true"></i>

Signup

</button>

</li>

<li>

<button type="button" class="login-btn" data-toggle="modal" data-target="#myModal">

<i class="fa fa-user" aria-hidden="true"></i>Login

</button>

</li>

<?php }

?>

<li>

<div id="side-menu-trigger" class="offcanvas-menu-btn">

<a href="#" class="menu-bar">

<span></span>

<span></span>

<span></span>

</a>

<a href="#" class="menu-times close">

<span></span>

<span></span>

</a>

</div>

</li>

</ul>

</div>

</div>

</div>

</div>

</div>

</div>

</header>

<!-- Header Area End Here -->

<!-- News Feed Area Start Here -->

<section class="bg-accent border-bottom add-top-margin">

<div class="container">

<div class="row no-gutters d-flex align-items-center">

<div class="col-lg-2 col-md-3 col-sm-4 col-6">

<div class="topic-box topic-box-margin">Top Stories</div>

</div>

<div class="col-lg-10 col-md-9 col-sm-8 col-6">

<div class="feeding-text-dark">

<ol id="sample" class="ticker">

<li>

<a href="#">McDonell Kanye West highlights difficulties for celebritiesComplimentary decor and

design advicewith Summit Park homes</a>

</li>

<li>

<a href="#">Magnificent Image Of The New Hoover Dam Bridge Taking Shape</a>

</li>

<li>

<a href="#">If Obama Had Governed Like This in 2017 He'd Be the Transformational.</a>

</li>

</ol>

</div>

</div>

</div>

</div>

</section>

<!-- News Feed Area End Here -->

<!-- News Info List Area Start Here -->

<section class="bg-div">

<div class="container">

<ul class="news-info-list text-center--md">

<li>

<i class="fa fa-map-marker" aria-hidden="true"></i>Australia</li>

<li>

<i class="fa fa-calendar" aria-hidden="true"></i><span id="current_date"></span></li>

<li>

<i class="fa fa-clock-o" aria-hidden="true"></i>Last Update 11.30 am</li>

<li>

<i class="fa fa-cloud" aria-hidden="true"></i>29&#8451; Sydney, Australia</li>

</ul>

</div>

</section>

<!-- Đăng nhập-->

<div class="modal fade" id="myModal" role="dialog">

<div class="modal-dialog">

<div class="modal-content">

<div class="modal-header">

<button type="button" class="close" data-dismiss="modal">&times;</button>

<div class="title-login-form">Đăng nhập</div>

</div>

<div class="modal-div">

<div class="login-form">

<form method="post">

<label>Tên đăng nhập *</label>

<input name="username" type="text" placeholder="Tên đăng nhập" />

<label>Mật khẩu *</label>

<input name="password" type="password" placeholder="Mật khẩu" />

<div class="checkbox checkbox-primary">

<input id="checkbox" type="checkbox" checked>

<label for="checkbox">Nhớ mật khẩu</label>

</div>

<button type="submit" name="login" value="Login">Đăng nhập</button>

<button class="form-cancel" type="submit" value="">Hủy</button>

<label class="lost-password">

<a href="#">Quên mật khẩu?</a>

</label>

</form>

</div>

</div>

</div>

</div>

</div>

<!-- Đăng nhâp End-->

<!-- Đăng ký-->

<div class="modal fade" id="signup" role="dialog">

<div class="modal-dialog">

<div class="modal-content">

<div class="modal-header">

<button type="button" class="close" data-dismiss="modal">&times;</button>

<div class="title-login-form">Đăng ký </div>

</div>

<div class="modal-div">

<div class="login-form">

<form method="post">

<label>Tên đăng nhập *</label>

<input type="text" name="username" placeholder="Tên đăng nhập" />

<label>Mật khẩu *</label>

<input type="password" name="password" placeholder="Mật khẩu" />

<label>Họ và tên *</label>

<input type="text" name="full_name" placeholder="Họ tên" />

<button type="submit" value="Login" name="signup">Đăng ký</button>

<button class="form-cancel" type="submit" value="">Hủy</button>

</form>

</div>

</div>

</div>

</div>

</div>

<!-- Đăng ký End-->

Kết quả sau khi chạy chương trình:

Chúng có thể vào trong phpmyadmin chỉnh sửa level = 1, lúc này khi đăng nhập lại trang sẽ được chuyển hướng vào trang quản trị viên Admin.

  • Tạo giao diện đăng nhập Admin

Tạo file View/client/pages/login_admin.php và chèn đoạn code sau:

<section class="bg-accent section-space-less2">

<div class="container">

<div class="modal-header">

<div class="title-login-form">Đăng nhập Admin</div>

</div>

<div class="login-form">

<form method="post">

<label>Tên đăng nhập *</label>

<input name="username_admin" type="text" placeholder="Tên đăng nhập" />

<label>Mật khẩu *</label>

<input name="password_admin" type="password" placeholder="Mật khẩu" />

<button type="submit" name="login_admin" value="Login">Đăng nhập</button>

</form>

</div>

</div>

</section>

Chạy đường dẫn để hiển thị giao diện đăng nhập Admin:
http://localhost/blog/?controller=login

  • Viết chức năng đăng nhập

Tạo file Controller/client/login.php

Kiểm tra nếu tồn tại $_SESSION['useradmin'] chuyển hướng vào trang admin ngược lại hiển thị giao diện đăng nhập Admin

public function __construct()

{

/**

* Nếu tồn tại $_SESSION['useradmin'] chuyển hướng vào trang admin

* Ngược lại hiển thị giao diện đăng nhập

* @var array

*/

if (!empty($_SESSION['useradmin'])) {

header('Location: View/admin');

} else {

$userModel = new UserModel();

$error = $this->loginAdmin($userModel);

require('View/client/pages/login_admin.php');

}

}

Viết hàm đăng nhập:

public function loginAdmin($userModel)

{

$username = $password = $fullName = NULL;

$error = array();

$error['username_admin'] = $error['password_admin'] = NULL;

if (!empty($_POST['login_admin'])) {

if (empty($_POST['username_admin'])) {

$error['username_admin'] = '* Cần điền tên đăng nhập';

} else {

$username = $_POST['username_admin'];

}

if (empty($_POST['password_admin'])) {

$error['password_admin'] = '* Cần điền mật khẩu';

} else {

$password = md5(md5($_POST['password_admin']));

}

if ($username && $password) {

$result = $userModel->login($username, $password);

$check = $result->num_rows; /*đếm số dòng trong database*/

/**

* Nếu số dòng trong database > 0 => lưu session + lấy dữ liệu + chuyển hướng

* Ngược lại thông báo alert bằng script

* @var array

*/

if ($check > 0) {

$data = $result->fetch_array(); /*lấy dữ liệu tương ứng với username và password nhập*/

$_SESSION['useradmin'] = $data; /*lưu session*/

/**

* Nếu level = 1 thì chuyển hướng đến trang quản trị viên

* Ngược lại thì thông báo đăng nhập lại

* @var array

*/

if ($data['level'] == admin) {

header('Location: View/admin');

} else {

echo "<script>alert('Vui lòng đăng nhập lại')</script>";

}

} else {

echo "<script>alert('Sai mật khẩu hoặc tên đăng nhập')</script>";

}

}

}

return $error;

}

File Controller/client/login.php hoàn chỉnh:

<?php

class Login

{

public function __construct()

{

/**

* Nếu tồn tại $_SESSION['useradmin'] chuyển hướng vào trang admin

* Ngược lại hiển thị giao diện đăng nhập

* @var array

*/

if (!empty($_SESSION['useradmin'])) {

header('Location: View/admin');

} else {

$userModel = new UserModel();

$error = $this->loginAdmin($userModel);

require('View/client/pages/login_admin.php');

}

}

public function loginAdmin($userModel)

{

$username = $password = $fullName = NULL;

$error = array();

$error['username_admin'] = $error['password_admin'] = NULL;

if (!empty($_POST['login_admin'])) {

if (empty($_POST['username_admin'])) {

$error['username_admin'] = '* Cần điền tên đăng nhập';

} else {

$username = $_POST['username_admin'];

}

if (empty($_POST['password_admin'])) {

$error['password_admin'] = '* Cần điền mật khẩu';

} else {

$password = md5(md5($_POST['password_admin']));

}

if ($username && $password) {

$result = $userModel->login($username, $password);

$check = $result->num_rows; /*đếm số dòng trong database*/

/**

* Nếu số dòng trong database > 0 => lưu session + lấy dữ liệu + chuyển hướng

* Ngược lại thông báo alert bằng script

* @var array

*/

if ($check > 0) {

$data = $result->fetch_array(); /*lấy dữ liệu tương ứng với username và password nhập*/

$_SESSION['useradmin'] = $data; /*lưu session*/

/**

* Nếu level = 1 thì chuyển hướng đến trang quản trị viên

* Ngược lại thì thông báo đăng nhập lại

* @var array

*/

if ($data['level'] == admin) {

header('Location: View/admin');

} else {

echo "<script>alert('Vui lòng đăng nhập lại')</script>";

}

} else {

echo "<script>alert('Sai mật khẩu hoặc tên đăng nhập')</script>";

}

}

}

return $error;

}

}

Trong file View/admin/index.php ta chỉnh lại như sau:

<?php

session_start(); /*đăng ký phiên làm việc*/

ob_start();

require '../../Config/config.php';

require '../../Model/Database.php';

$db = new Database();

/**

* Nếu tồn tại session và giá trị level = 1 thì có quyền truy cập trang quản trị viên

* Ngược lại thì chuyển hướng về trang chủ

* @var array

*/

if (!empty($_SESSION['useradmin']) && $_SESSION['useradmin']['level'] == admin) {

require('layouts/header.php');

if (isset($_GET['controller'])) {

require '../../Route/admin/web.php'; /*xử lý các request trong Route/web.php*/

} else {

require('pages/home.php');

}

require('layouts/footer.php');

} else {

header('Location: ../../');

}

$db->closeDatabase();

Lập trình chức năng đăng xuất

Chức năng đăng xuất hoạt động như sau: Khi người dùng truy cập vào trang đăng xuất thì sẽ lập tức xóa session người dùng, sau đó redirect lại trang mà mình tùy chỉnh.

Tạo file Controller/client/logout.php và chèn đoạn code sau:

<?php

class Logout {

public function __construct()

{

unset($_SESSION['user']); // xóa session user đã tạo khi đăng nhập

header('Location: ./'); // chuyển hướng về trang chủ

}

}

$logout = new Logout();

Viết đường dẫn đăng xuất, viết đoạn sau vào file View/admin/layouts/header.php:

<li style="margin-top: 5px; padding-left: 20px;" class="nav-item dropdown">

<a href="?controller=logoutAdmin">Đăng xuất</a>

</li>

File View/admin/layouts/header.php đầy đủ sau khi chèn:

<!DOCTYPE >

<>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title>AdminLTE 3 | Dashboard</title>

<!-- Tell the browser to be responsive to screen width -->

<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Font Awesome -->

<link rel="stylesheet" href="../../Public/admin/plugins/fontawesome-free/css/all.min.css">

<!-- Ionicons -->

<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">

<!-- Tempusdominus Bbootstrap 4 -->

<link rel="stylesheet" href="../../Public/admin/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">

<!-- iCheck -->

<link rel="stylesheet" href="../../Public/admin/plugins/icheck-bootstrap/icheck-bootstrap.min.css">

<!-- JQVMap -->

<link rel="stylesheet" href="../../Public/admin/plugins/jqvmap/jqvmap.min.css">

<!-- Theme style -->

<link rel="stylesheet" href="../../Public/admin/dist/css/adminlte.min.css">

<!-- overlayScrollbars -->

<link rel="stylesheet" href="../../Public/admin/plugins/overlayScrollbars/css/OverlayScrollbars.min.css">

<!-- Daterange picker -->

<link rel="stylesheet" href="../../Public/admin/plugins/daterangepicker/daterangepicker.css">

<!-- summernote -->

<link rel="stylesheet" href="../../Public/admin/plugins/summernote/summernote-bs4.css">

<!-- Google Font: Source Sans Pro -->

<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">

</head>

<div class="hold-transition sidebar-mini layout-fixed">

<div class="wrapper">

<!-- Navbar -->

<nav class="main-header navbar navbar-expand navbar-white navbar-light">

<!-- Left navbar links -->

<ul class="navbar-nav">

<li class="nav-item">

<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>

</li>

<li class="nav-item d-none d-sm-inline-block">

<a href="#" class="nav-link">Home</a>

</li>

<li class="nav-item d-none d-sm-inline-block">

<a href="#" class="nav-link">Contact</a>

</li>

</ul>

<!-- SEARCH FORM -->

<form class="form-inline ml-3">

<div class="input-group input-group-sm">

<input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">

<div class="input-group-append">

<button class="btn btn-navbar" type="submit">

<i class="fas fa-search"></i>

</button>

</div>

</div>

</form>

<!-- Right navbar links -->

<ul class="navbar-nav ml-auto">

<!-- Messages Dropdown Menu -->

<li class="nav-item dropdown">

<a class="nav-link" data-toggle="dropdown" href="#">

<i class="far fa-comments"></i>

<span class="badge badge-danger navbar-badge">3</span>

</a>

<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">

<a href="#" class="dropdown-item">

<!-- Message Start -->

<div class="media">

<img src="../../Public/admin/dist/img/user1-128x128.jpg" alt="User Avatar" class="img-size-50 mr-3 img-circle">

<div class="media-div">

<h3 class="dropdown-item-title">

Brad Diesel

<span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>

</h3>

<p class="text-sm">Call me whenever you can...</p>

<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>

</div>

</div>

<!-- Message End -->

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<!-- Message Start -->

<div class="media">

<img src="../../Public/admin/dist/img/user8-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">

<div class="media-div">

<h3 class="dropdown-item-title">

John Pierce

<span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>

</h3>

<p class="text-sm">I got your message bro</p>

<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>

</div>

</div>

<!-- Message End -->

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<!-- Message Start -->

<div class="media">

<img src="../../Public/admin/dist/img/user3-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">

<div class="media-div">

<h3 class="dropdown-item-title">

Nora Silvester

<span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span>

</h3>

<p class="text-sm">The subject goes here</p>

<p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>

</div>

</div>

<!-- Message End -->

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item dropdown-footer">See All Messages</a>

</div>

</li>

<!-- Notifications Dropdown Menu -->

<li class="nav-item dropdown">

<a class="nav-link" data-toggle="dropdown" href="#">

<i class="far fa-bell"></i>

<span class="badge badge-warning navbar-badge">15</span>

</a>

<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">

<span class="dropdown-item dropdown-header">15 Notifications</span>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<i class="fas fa-envelope mr-2"></i> 4 new messages

<span class="float-right text-muted text-sm">3 mins</span>

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<i class="fas fa-users mr-2"></i> 8 friend requests

<span class="float-right text-muted text-sm">12 hours</span>

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item">

<i class="fas fa-file mr-2"></i> 3 new reports

<span class="float-right text-muted text-sm">2 days</span>

</a>

<div class="dropdown-divider"></div>

<a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>

</div>

</li>

<li style="margin-top: 5px; padding-left: 20px;" class="nav-item dropdown">

<a href="?controller=logoutAdmin">Đăng xuất</a>

</li>

</ul>

</nav>

<!-- Main Sidebar Container -->

<aside class="main-sidebar sidebar-dark-primary elevation-4">

<!-- Brand Logo -->

<a href="index3." class="brand-link">

<img src="../../Public/admin/dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8">

<span class="brand-text font-weight-light">Admin</span>

</a>

<!-- Sidebar -->

<div class="sidebar">

<!-- Sidebar user panel (optional) -->

<div class="user-panel mt-3 pb-3 mb-3 d-flex">

<div class="image">

<img src="../../Public/admin/dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">

</div>

<div class="info">

<a href="#" class="d-block">Nguyễn Trọng Chính</a>

</div>

</div>

<!-- Sidebar Menu -->

<nav class="mt-2">

<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">

<!-- Add icons to the links using the .nav-icon class

with font-awesome or any other icon font library -->

<li class="nav-item has-treeview">

<a href="index.php" class="nav-link active">

<i class="nav-icon fas fa-tachometer-alt"></i>

<p>

Trang chủ

</p>

</a>

</li>

<li class="nav-item has-treeview">

<a href="#" class="nav-link">

<i class="nav-icon fas fa-copy"></i>

<p>

Chuyên mục

<i class="fas fa-angle-left right"></i>

<span class="badge badge-info right">6</span>

</p>

</a>

<ul class="nav nav-treeview">

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Thêm</p>

</a>

</li>

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Danh sách</p>

</a>

</li>

</ul>

</li>

<li class="nav-item has-treeview">

<a href="#" class="nav-link">

<i class="nav-icon fas fa-copy"></i>

<p>

Bài viết

<i class="fas fa-angle-left right"></i>

<span class="badge badge-info right">6</span>

</p>

</a>

<ul class="nav nav-treeview">

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Thêm</p>

</a>

</li>

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Danh sách</p>

</a>

</li>

</ul>

</li>

<li class="nav-item has-treeview">

<a href="#" class="nav-link">

<i class="nav-icon fas fa-copy"></i>

<p>

Thành viên

<i class="fas fa-angle-left right"></i>

<span class="badge badge-info right">6</span>

</p>

</a>

<ul class="nav nav-treeview">

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Thêm</p>

</a>

</li>

<li class="nav-item">

<a href="#" class="nav-link">

<i class="far fa-circle nav-icon"></i>

<p>Danh sách</p>

</a>

</li>

</ul>

</li>

</ul>

</nav>

<!-- /.sidebar-menu -->

</div>

<!-- /.sidebar -->

</aside>

Thêm chuyên mục

Trong SEO, đường dẫn URL tốt sẽ giúp cho Google index dễ dàng hơn. URL chứa từ khóa sẽ làm tăng giá trị của bài viết. Vì vậy chúng ta sẽ viết một hàm chuyển đổi để đường dẫn url thân thiện với google hơn, ví dụ đường dẫn sẽ có dạng: 

https://safedownload.net/tai-phan-mem/chicken-invaders

Tạo file Lib/function.php và chèn đoạn code sau đây vào:

<?php

function changeTitle($str,$strSymbol='-',$case=MB_CASE_LOWER){// MB_CASE_UPPER / MB_CASE_TITLE / MB_CASE_LOWER

$str=trim($str);

if ($str=="") return "";

$str =str_replace('"','',$str);

$str =str_replace("'",'',$str);

$str = stripUnicode($str);

$str = mb_convert_case($str,$case,'utf-8');

$str = preg_replace('/[\W|_]+/',$strSymbol,$str);

return $str;

}

function stripUnicode($str){

if(!$str) return '';

//$str = str_replace($a, $b, $str);

$unicode = array(

'a'=>'á|à|ả|ã|ạ|ă|ắ|ằ|ẳ|ẵ|ặ|â|ấ|ầ|ẩ|ẫ|ậ|å|ä|æ|ā|ą|ǻ|ǎ',

'A'=>'Á|À|Ả|Ã|Ạ|Ă|Ắ|Ằ|Ẳ|Ẵ|Ặ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ|Å|Ä|Æ|Ā|Ą|Ǻ|Ǎ',

'ae'=>'ǽ',

'AE'=>'Ǽ',

'c'=>'ć|ç|ĉ|ċ|č',

'C'=>'Ć|Ĉ|Ĉ|Ċ|Č',

'd'=>'đ|ď',

'D'=>'Đ|Ď',

'e'=>'é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ|ë|ē|ĕ|ę|ė',

'E'=>'É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ|Ë|Ē|Ĕ|Ę|Ė',

'f'=>'ƒ',

'F'=>'',

'g'=>'ĝ|ğ|ġ|ģ',

'G'=>'Ĝ|Ğ|Ġ|Ģ',

'h'=>'ĥ|ħ',

'H'=>'Ĥ|Ħ',

'i'=>'í|ì|ỉ|ĩ|ị|î|ï|ī|ĭ|ǐ|į|ı',

'I'=>'Í|Ì|Ỉ|Ĩ|Ị|Î|Ï|Ī|Ĭ|Ǐ|Į|İ',

'ij'=>'ij',

'IJ'=>'IJ',

'j'=>'ĵ',

'J'=>'Ĵ',

'k'=>'ķ',

'K'=>'Ķ',

'l'=>'ĺ|ļ|ľ|ŀ|ł',

'L'=>'Ĺ|Ļ|Ľ|Ŀ|Ł',

'o'=>'ó|ò|ỏ|õ|ọ|ô|ố|ồ|ổ|ỗ|ộ|ơ|ớ|ờ|ở|ỡ|ợ|ö|ø|ǿ|ǒ|ō|ŏ|ő',

'O'=>'Ó|Ò|Ỏ|Õ|Ọ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ|Ö|Ø|Ǿ|Ǒ|Ō|Ŏ|Ő',

'Oe'=>'œ',

'OE'=>'Œ',

'n'=>'ñ|ń|ņ|ň|ʼn',

'N'=>'Ñ|Ń|Ņ|Ň',

'u'=>'ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự|û|ū|ŭ|ü|ů|ű|ų|ǔ|ǖ|ǘ|ǚ|ǜ',

'U'=>'Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự|Û|Ū|Ŭ|Ü|Ů|Ű|Ų|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ',

's'=>'ŕ|ŗ|ř',

'R'=>'Ŕ|Ŗ|Ř',

's'=>'ß|ſ|ś|ŝ|ş|š',

'S'=>'Ś|Ŝ|Ş|Š',

't'=>'ţ|ť|ŧ',

'T'=>'Ţ|Ť|Ŧ',

'w'=>'ŵ',

'W'=>'Ŵ',

'y'=>'ý|ỳ|ỷ|ỹ|ỵ|ÿ|ŷ',

'Y'=>'Ý|Ỳ|Ỷ|Ỹ|Ỵ|Ÿ|Ŷ',

'z'=>'ź|ż|ž',

'Z'=>'Ź|Ż|Ž'

);

foreach($unicode as $khongdau=>$codau) {

$arr=explode("|",$codau);

$str = str_replace($arr,$khongdau,$str);

}

return $str;

}

?>

Require function này trong file View/admin/index.php:

require '../../Lib/function.php';

File View/admin/index.php sau khi chỉnh sửa:

<?php

session_start(); /*đăng ký phiên làm việc*/

ob_start();

require '../../Config/config.php';

require '../../Lib/function.php';

require '../../Model/Database.php';

$db = new Database();

/**

* Nếu tồn tại session và giá trị level = 1 thì có quyền truy cập trang quản trị viên

* Ngược lại thì chuyển hướng về trang chủ

* @var array

*/

if (!empty($_SESSION['useradmin']) && $_SESSION['useradmin']['level'] == admin) {

require('layouts/header.php');

if (isset($_GET['controller'])) {

require '../../Route/admin/web.php'; /*xử lý các request trong Route/web.php*/

} else {

require('pages/home.php');

}

require('layouts/footer.php');

} else {

header('Location: ../../');

}

$db->closeDatabase();

2) Làm chức năng thêm chuyên mục

Đầu tiên chúng ta sẽ đi thiết kế giao diện thêm chuyên mục. Tạo file View/admin/pages/category/add.php và chèn đoạn code sau đây vào: 

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Thêm chuyên mục</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Chuyên mục</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post">

<div class="card-div">

<div class="form-group">

<label for="exampleInputEmail1">Tên chuyên mục</label>

<input type="text" name="name" class="form-control" placeholder="Tên chuyên mục">

</div>

<button type="submit" name="addCategory" class="btn btn-primary">Thêm</button>

</div>

</form>

</div>

</section>

</div>

Tiếp theo, tạo file Controller/admin/addCategory.php:

<?php

class AddCategory {

public function __construct()

{

require('pages/category/add.php');

}

}

Chạy chương trình theo đường dẫn: http://localhost/blog/View/admin/?controller=addCategory để xem kết quả:

Tạo file Model/admin/category.php viết hàm xử lý với database:

<?php

class CategoryModel extends Database{

protected $db;

public function __construct()

{

$this->db = new Database();

$this->db->connect();

}

public function addCategory($name, $slug)

{

$this->db->conn->real_escape_string($name);

$sql = "INSERT INTO categories (name, slug)

VALUES ('$name', '$slug')";

$this->db->conn->query($sql);

}

}

Thực hiện xử lý form trong file Controller/admin/addCategory.php:

<?php

class AddCategory {

public function __construct()

{

require('../../Model/admin/category.php');

$categoryModel = new CategoryModel();

$name = $slug = NULL;

$alert = array();

if (isset($_POST['addCategory'])) {

$name = $_POST['name'];

$slug = changeTitle($name);

if ($name) {

$categoryModel->addCategory($name, $slug);

$alert['success'] = 'Thêm thành công';

}

}

require('pages/category/add.php');

}

}

Xử lý hiện thông báo khi thêm chuyên mục thành công trong file View/admin/pages/category/add.php:

<?php

if (isset($alert['success'])) {?>

<div class="form-group alert alert-primary">

<?=$alert['success']?>

</div>

<?php }

?>

File View/admin/pages/category/add.php hoàn chỉnh sau khi hiển thị thông báo:

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Thêm chuyên mục</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Chuyên mục</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post">

<div class="card-div">

<?php

if (isset($alert['success'])) {?>

<div class="form-group alert alert-primary">

<?=$alert['success']?>

</div>

<?php }

?>

<div class="form-group">

<label>Tên chuyên mục</label>

<input type="text" name="name" class="form-control" placeholder="Tên chuyên mục">

</div>

<button type="submit" name="addCategory" class="btn btn-primary">Thêm</button>

</div>

</form>

</div>

</section>

</div>

Lập trình chức năng sửa chuyên mục và hiển thị danh sách chuyên mục

Đầu tiên chúng ta sẽ thiết kế giao diện danh sách chuyên mục và giao diện chỉnh sửa chuyên mục.

Tạo file View/admin/pages/catefory/list.php và viết đoạn code sau:

<div class="content-wrapper" style="min-height: 1203.6px;">

<section class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1>Danh sách chuyên mục</h1>

</div>

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Home</a></li>

<li class="breadcrumb-item active">Danh sách chuyên mục</li>

</ol>

</div>

</div>

</div>

</section>

<section>

<div class="col-12">

<div class="card">

<!-- /.card-header -->

<div class="card-div">

<div id="example2_wrapper" class="dataTables_wrapper dt-bootstrap4">

<div class="row">

<div class="col-sm-12 col-md-6"></div>

<div class="col-sm-12 col-md-6"></div>

</div>

<div class="row">

<div class="col-sm-12">

<table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info">

<thead>

<tr role="row">

<th class="sorting_asc" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Rendering engine: activate to sort column descending">STT</th>

<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Browser: activate to sort column ascending">Tên chuyên mục</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Platform(s): activate to sort column ascending">Sửa</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Xóa</th>

</tr>

</thead>

<tdiv>

<tr role="row" class="odd">

<td class="sorting_1">1</td>

<td>Đời sống</td>

<td style="text-align: center;">

<span class="badge bg-primary">

<ion-icon name="create-outline"></ion-icon>

</span>

</td>

<td style="text-align: center;">

<span class="badge bg-danger">

<ion-icon name="trash-outline"></ion-icon>

</span>

</td>

</tr>

</tdiv>

<tfoot>

<tr>

<th rowspan="1" colspan="1">STT</th>

<th rowspan="1" colspan="1">Tên chuyên mục</th>

<th rowspan="1" colspan="1">Sửa</th>

<th rowspan="1" colspan="1">Xóa</th>

</tr>

</tfoot>

</table>

</div>

</div>

</div>

</div>

<!-- /.card-div -->

</div>

</div>

</section>

</div>

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=listCategory để xem kết quả:

Tiếp theo thiết kế giao diện sửa chuyên mục, tạo file View/admin/pages/catefory/edit.php và viết đoạn code sau:   

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Sửa chuyên mục</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Chuyên mục</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post">

<div class="card-div">

<div class="form-group">

<label>Tên chuyên mục</label>

<input type="text" name="name" class="form-control" placeholder="Tên chuyên mục">

</div>

<button type="submit" name="addCategory" class="btn btn-primary">Hoàn thành</button>

</div>

</form>

</div>

</section>

</div>

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=editCategory để xem kết quả:

Lập trình chức năng hiển thị danh sách chuyên mục

Viết hàm categoryList lấy chuyên mục từ cơ sở dữ liệu trong file Model/admin/category.php:

public function categoryList(){

$sql = "SELECT * FROM categories";

$result = $this->db->conn->query($sql);

$list = array();

while($data = $result->fetch_array()) {

$list[] = $data;

}

return $list;

}

File Model/admin/category.php hoàn chỉnh:

<?php

class CategoryModel extends Database{

protected $db;

public function __construct()

{

$this->db = new Database();

$this->db->connect();

}

public function addCategory($name, $slug)

{

$this->db->conn->real_escape_string($name);

$sql = "INSERT INTO categories (name, slug)

VALUES ('$name', '$slug')";

$this->db->conn->query($sql);

}

public function getCategory($categoryId)

{

$sql = "SELECT * FROM categories WHERE id = $categoryId";

$result = $this->db->conn->query($sql);

$data = $result->fetch_array();

return $data;

}

public function categoryList()

{

$sql = "SELECT * FROM categories";

$result = $this->db->conn->query($sql);

$list = array();

while($data = $result->fetch_array()) {

$list[] = $data;

}

return $list;

}

}

Bây giờ chúng ta xử lý logic bên Controller, tạo file Controller/admin/listCategory.php và viết đoạn code sau:

<?php

class ListCategory {

public function __construct()

{

require_once('../../Model/admin/category.php');

$categoryModel = new CategoryModel();

$categories = $categoryModel->categoryList();

require('pages/category/list.php');

}

}

Hiển thị giữ liệu lấy được ra view, trong file View/admin/pages/catefory/list.php và viết đoạn code sau:

<div class="content-wrapper" style="min-height: 1203.6px;">

<section class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1>Danh sách chuyên mục</h1>

</div>

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Home</a></li>

<li class="breadcrumb-item active">Danh sách chuyên mục</li>

</ol>

</div>

</div>

</div>

</section>

<section>

<div class="col-12">

<div class="card">

<!-- /.card-header -->

<div class="card-div">

<div id="example2_wrapper" class="dataTables_wrapper dt-bootstrap4">

<div class="row">

<div class="col-sm-12 col-md-6"></div>

<div class="col-sm-12 col-md-6"></div>

</div>

<div class="row">

<div class="col-sm-12">

<?php

if (isset($_SESSION['thongbao'])) {?>

<div class="form-group alert alert-primary">

<?=$_SESSION['thongbao']?>

<?php unset($_SESSION['thongbao']); ?>

</div>

<?php }

?>

<table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info">

<thead>

<tr role="row">

<th class="sorting_asc" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Rendering engine: activate to sort column descending">STT</th>

<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Browser: activate to sort column ascending">Tên chuyên mục</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Platform(s): activate to sort column ascending">Sửa</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Xóa</th>

</tr>

</thead>

<tdiv>

<?php

$stt = 0;

foreach ($categories as $category) {?>

<tr role="row" class="odd">

<td class="sorting_1"><?=++$stt?></td>

<td><?=$category['name']?></td>

<td style="text-align: center;">

<span class="badge bg-primary">

<a href="?controller=editCategory&categoryId=<?=$category['id']?>">

<ion-icon name="create-outline"></ion-icon>

</a>

</span>

</td>

<td style="text-align: center;">

<span class="badge bg-danger">

<a href="#">

<ion-icon name="trash-outline"></ion-icon>

</a>

</span>

</td>

</tr>

<?php }

?>

</tdiv>

<tfoot>

<tr>

<th rowspan="1" colspan="1">STT</th>

<th rowspan="1" colspan="1">Tên chuyên mục</th>

<th rowspan="1" colspan="1">Sửa</th>

<th rowspan="1" colspan="1">Xóa</th>

</tr>

</tfoot>

</table>

</div>

</div>

</div>

</div>

<!-- /.card-div -->

</div>

</div>

</section>

</div>

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=listCategory để xem kết quả  

Lập trình chức năng sửa chuyên mục

Viết hàm getCategory lấy dữ liệu chuyên mục theo id trong file Model/admin/category.php:  

public function getCategory($categoryId){

$sql = "SELECT * FROM categories WHERE id = $categoryId";

$result = $this->db->conn->query($sql);

$data = $result->fetch_array();

return $data;

}

Thêm hàm editCategory sửa chuyên mục trong file Model/admin/category.php:   

public function editCategory($categoryId){

$sql = "UPDATE categories SET name = '$name' WHERE id = $categoryId";

return $this->db->conn->query($sql);

}

Bây giờ chúng ta xử lý logic bên Controller, tạo file Controller/admin/editCategory.php và chèn đoạn code sau:  

<?php

class EditCategory {

public function __construct()

{

require_once('../../Model/admin/category.php');

$categoryModel = new CategoryModel();

$name = $slug = NULL;

if (isset($_GET['categoryId'])) {

$categoryId = $_GET['categoryId'];

$categoryOld = $categoryModel->getCategory($categoryId);

if (isset($_POST['editCategory'])) {

$name = $_POST['name'];

$slug = changeTitle($name);

$categoryModel->editCategory($name, $slug, $categoryId);

$_SESSION['thongbao'] = '* Thêm thành công';

header('Location: ?controller=listCategory');

}

require('pages/category/edit.php');

}

}

}

Hiển thị tên chuyên mục cũ muốn sửa trong file View/admin/pages/category/edit:

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Sửa chuyên mục</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Chuyên mục</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post">

<div class="card-div">

<div class="form-group">

<label>Tên chuyên mục</label>

<input type="text" value="<?=$categoryOld['name']?>" name="name" class="form-control" placeholder="Tên chuyên mục">

</div>

<button type="submit" name="editCategory" class="btn btn-primary">Hoàn thành</button>

</div>

</form>

</div>

</section>

</div>

Hiển thị thông báo sau khi sửa thành công, viết đoạn code sau vào file View/admin/pages/category/list:

<?php

if (isset($_SESSION['thongbao'])) {?>

<div class="form-group alert alert-primary">

<?=$_SESSION['thongbao']?>

<?php unset($_SESSION['thongbao']); ?>

</div>

<?php }

?>

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=editCategory&categoryId=$category để chỉnh sửa chuyên mục. Biến $category sẽ là giá trị cột id trong bảng categories.

Lập trình chức năng thêm bài viết

  • Thiết kế giao diện thêm bài viết

Tạo file View/admin/pages/post/add.php và chèn đoạn code sau:

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Thêm bài viết</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Bài viết</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post">

<div class="card-div">

<div class="form-group">

<label>Tiêu đề</label>

<input type="text" required="required" name="title" class="form-control" placeholder="Tên chuyên mục">

</div>

<div class="form-group">

<label>Chuyên mục</label>

<select name="category_id" class="form-control select2">

<option>1</option>

</select>

</div>

<div class="form-group">

<label>Tóm tắt</label>

<textarea class="textarea" name="summary" required="required" placeholder="Place some text here"

style="width: 100%; height: 500px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;"></textarea>

</div>

<div class="form-group">

<label>Nội dung</label>

<textarea required="required" name="content" class="textarea" placeholder="Place some text here"

style="width: 100%; height: 500px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;"></textarea>

</div>

<button type="submit" name="addCategory" class="btn btn-primary">Thêm</button>

</div>

</form>

</div>

</section>

</div>

Sau khi lưu file add.php, tạo file Controller/admin/addPost.php và thực hiện require View để hiển thị lên màn hình:

<?php

class AddPost

{

public function __construct()

{

require('pages/post/add.php');

}

}

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=addPost để xem kết quả:

Viết code chức năng thêm bài viết

Viết hàm addPost - thêm bài viết trong file Model/admin/post.php và viết đoạn code sau:

<?php

class PostModel extends Database{

protected $db;

public function __construct()

{

$this->db = new Database();

$this->db->connect();

}

public function addPost($title, $slug, $summary, $content, $categoryId, $userId, $date)

{

$title = $this->db->conn->real_escape_string($title);

$slug = $this->db->conn->real_escape_string($slug);

$summary = $this->db->conn->real_escape_string($summary);

$content = $this->db->conn->real_escape_string($content);

$sql = "INSERT INTO posts (title, slug, summary, content, category_id, user_id, date)

VALUES ('$title', '$slug', '$summary', '$content', '$categoryId', '$userId', '$date')";

return $this->db->conn->query($sql);

}

}

Xử lý logic bên Controller, trong file Controller/admin/addPost.php và viết đoạn code sau:

<?php

class AddPost

{

public function __construct()

{

require_once('../../Model/admin/category.php');

$categoryModel = new CategoryModel();

$postModel = new PostModel();

$categories = $categoryModel->categoryList(); /*lấy tất cả chuyên mục*/

if (isset($_POST['addPost'])) {

$title = $_POST['title'];

$slug = changeTitle($title);

$summary = $_POST['summary'];

$content = $_POST['content'];

$userId = $_SESSION['useradmin'];

$categoryId = $_POST['category_id'],

$date = date('Y-m-d');

$postModel->addPost($title, $slug, $summary, $content, $userId, $categoryId, $date);

}

require('pages/post/add.php');

}

}

Hiển thị chuyên mục bên View, trong file View/admin/pages/post/add.php sửa:

<select name="category_id" class="form-control select2">

<option>1</option>

</select>

Thành:

<select name="category_id" class="form-control select2">

<?php

foreach ($categories as $category) {?>

<option value="<?=$category['id']?>"><?=$category['name']?></option>

<?php } ?>

</select>

Lập trình chức năng hiển thị danh sách bài viết

  • Thiết kế giao diện

Trước tiên chúng ta thiết kế giao diện danh sách bài viết, tạo file View/admin/pages/post/list.php và chèn đoạn code sau:

<div class="content-wrapper" style="min-height: 1203.6px;">

<section class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1>Danh sách chuyên mục</h1>

</div>

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Home</a></li>

<li class="breadcrumb-item active">Danh sách chuyên mục</li>

</ol>

</div>

</div>

</div>

</section>

<section>

<div class="col-12">

<div class="card">

<!-- /.card-header -->

<div class="card-div">

<div id="example2_wrapper" class="dataTables_wrapper dt-bootstrap4">

<div class="row">

<div class="col-sm-12 col-md-6"></div>

<div class="col-sm-12 col-md-6"></div>

</div>

<div class="row">

<div class="col-sm-12">

<?php

if (isset($_SESSION['thongbao'])) {?>

<div class="form-group alert alert-primary">

<?=$_SESSION['thongbao']?>

<?php unset($_SESSION['thongbao']); ?>

</div>

<?php }

?>

<table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info">

<thead>

<tr role="row">

<th class="sorting_asc" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Rendering engine: activate to sort column descending">STT</th>

<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Browser: activate to sort column ascending">Ảnh</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Platform(s): activate to sort column ascending">Tiêu đề</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">View</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Chuyên mục</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Ngươi tạo</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Ngày đăng</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Sửa</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Xóa</th>

</tr>

</thead>

<tdiv>

<tr>

<td>1</td>

<td>

hình ảnh

</td>

<td>

Sửa lỗi không vào được game trong Đấu Trường Chân Lý (ĐTCL)

</td>

<td>

1

</td>

<td>

Thể thao

</td>

<td>

admin

</td>

<td>

19/02/2020

</td>

<td style="text-align: center;">

<span class="badge bg-primary">

<a href="">

<ion-icon name="create-outline"></ion-icon>

</a>

</span>

</td>

<td style="text-align: center;">

<span class="badge bg-danger">

<a href="">

<ion-icon name="trash-outline"></ion-icon>

</a>

</span>

</td>

</tr>

</tdiv>

</table>

</div>

</div>

</div>

</div>

<!-- /.card-div -->

</div>

</div>

</section>

</div>

Sau khi lưu filetạo file Controller/admin/listPost.php và thực hiện require View để hiển thị lên màn hình:

<?php

class ListPost {

public function __construct()

{

require('pages/post/list.php');

}

}

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=listPost để xem kết quả:

  • Viết code hiển thị bài viết

Sau khi hoàn thành giao diện danh sách bài viết chúng ta bắt đầu tiến hành lấy giữ liệu từ CSDL và in ra danh sách bài viết.

Viết hàm postList trong Model/Controller/admin/post.php, hàm này có chức năng lấy toàn bộ bài viết trong bảng posts:

public function postList(){

$sql = "SELECT * FROM posts";

$result = $this->db->conn->query($sql);

$list = array();

while ($data = $result->fetch_array()) {

$list[] = $data;

}

return $list;

}

Tiếp theo bên Controller gọi hàm postList , khi đó file Controller/admin/listCategory.php sẽ như sau:

<?php

class ListPost {

public function __construct()

{

require_once('../../Model/admin/post.php');

$postModel = new PostModel;

$posts = $postModel->postList();

require('pages/post/list.php');

}

}

Cuối cùng, hiển thị danh sách sang View danh sách bài viết, khi đó file View/admin/pages/post/list.php sẽ trở thành:

<div class="content-wrapper" style="min-height: 1203.6px;">

<section class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1>Danh sách bài viết</h1>

</div>

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Home</a></li>

<li class="breadcrumb-item active">Danh sách bài viết</li>

</ol>

</div>

</div>

</div>

</section>

<section>

<div class="col-12">

<div class="card">

<!-- /.card-header -->

<div class="card-div">

<div id="example2_wrapper" class="dataTables_wrapper dt-bootstrap4">

<div class="row">

<div class="col-sm-12 col-md-6"></div>

<div class="col-sm-12 col-md-6"></div>

</div>

<div class="row">

<div class="col-sm-12">

<?php

if (isset($_SESSION['thongbao'])) {?>

<div class="form-group alert alert-primary">

<?=$_SESSION['thongbao']?>

<?php unset($_SESSION['thongbao']); ?>

</div>

<?php }

?>

<table id="example2" class="table table-bordered table-hover dataTable" role="grid" aria-describedby="example2_info">

<thead>

<tr role="row">

<th class="sorting_asc" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Rendering engine: activate to sort column descending">STT</th>

<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Browser: activate to sort column ascending">Ảnh</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Platform(s): activate to sort column ascending">Tiêu đề</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">View</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Chuyên mục</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Ngươi tạo</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Ngày đăng</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Sửa</th>

<th style="text-align: center;" class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-label="Engine version: activate to sort column ascending">Xóa</th>

</tr>

</thead>

<tdiv>

<?php

$stt = 0;

foreach ($posts as $post) {?>

<tr>

<td><?=++$stt?></td>

<td>

<img width="200px" src="../../Public/upload/posts/<?=$post['image']?>">

</td>

<td>

<?=$post['title']?>

</td>

<td>

<?=$post['view_number']?>

</td>

<td>

<?=$post['category_id']?>

</td>

<td>

<?=$post['user_id']?>

</td>

<td>

<?=$post['date']?>

</td>

<td style="text-align: center;">

<span class="badge bg-primary">

<a href="?controller=editPost&postId=<?=$post['id']?>">

<ion-icon name="create-outline"></ion-icon>

</a>

</span>

</td>

<td style="text-align: center;">

<span class="badge bg-danger">

<a href="?controller=deletePost&postId=<?=$post['id']?>">

<ion-icon name="trash-outline"></ion-icon>

</a>

</span>

</td>

</tr>

<?php }

?>

</tdiv>

</table>

</div>

</div>

</div>

</div>

<!-- /.card-div -->

</div>

</div>

</section>

</div>

Chạy chương trình theo đường dẫn sau: http://localhost/blog/View/admin/?controller=listPost để xem kết quả  

Lập trình chức năng sửa và xóa bài viết

  • Thiết kế giao diện

Vì là trang chỉnh sửa bài viết, nên nội dung của chúng có phần sẽ giống với phần thêm bài viết, chỉ khác là các ô nhập liệu giờ đây đã có dữ liệu. Dữ liệu này chúng ta tiến hành lấy từ cơ sở dữ liệu thông qua biến truyền mà ở danh sách bài viết đã gửi editPost.php?postId=$id. Biến $id sẽ là giá trị id của bài viết mà chúng ta truyền vào.

Tạo file View/admin/pages/post/edit.php:

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Sửa bài viết</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Bài viết</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post" enctype="multipart/form-data">

<div class="card-div">

<div class="form-group">

<label>Tiêu đề</label>

<input type="text" required="required" name="title" class="form-control" placeholder="Tên chuyên mục">

</div>

<div class="form-group">

<label>Chuyên mục</label>

<select name="category_id" class="form-control select2">

<option>Thể thao</option>

</select>

</div>

<div class="form-group">

<label>Ảnh cũ</label><br>

<img width="200px" src="">

<input type="hidden" value="" name="image_old">

</div>

<div class="form-group">

<label for="exampleInputFile">Chọn ảnh</label>

<div class="input-group">

<div class="custom-file">

<input type="file" name="image" class="custom-file-input" id="exampleInputFile">

<label class="custom-file-label" for="exampleInputFile">Chọn ảnh</label>

</div>

</div>

<div class="form-group">

<label>Tóm tắt</label>

<textarea class="textarea" name="summary" required="required" placeholder="Place some text here"

style="width: 100%; height: 500px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;"></textarea>

</div>

<div class="form-group">

<label>Nội dung</label>

<textarea required="required" name="content" class="textarea" placeholder="Place some text here"

style="width: 100%; height: 500px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;"></textarea>

</div>

<button type="submit" name="editPost" class="btn btn-primary">Hoàn thành</button>

</div>

</form>

</div>

</section>

</div>

Sau khi thiết kế xong phần giao diện, để hiển thị chúng ta cần require nó trong controller, tạo file Controller/admin/editPost.php:

<?php

class EditPost {

public function __construct()

{

require('pages/post/edit.php');

}

}

Chạy chương trình theo đường dẫn: http://localhost/blog/View/admin/?controller=editPost&postId=$id để xem kết quả, biến $id sẽ là id bài viết mà bạn muốn chỉnh sửa.

  • Viết code chức năng sửa bài viết

  • Hiển thị dữ liệu cũ

Để tiện cho việc chỉnh sửa, chúng ta cần in những nội dung cũ mà ta đã thêm trước đó vào form chỉnh sửa. Viết hàm getPost trong file để thực hiện thao tác lấy dữ liệu bài viết theo id.

public function getPost($postId){

$sql = "SELECT * FROM posts WHERE id = $postId";

$result = $this->db->conn->query($sql);

$data = $result->fetch_array();

return $data;

}

Ta thấy trong form sửa bài viết có mục chọn chuyên mục, để hiện thị toàn bộ chuyên mục thì chúng ta cần lấy tất cả chuyên mục có trong CSDL, sửa file Controller/admin/editPost thành:

<?php

class EditPost {

public function __construct()

{

require_once('../../Model/admin/category.php');

require_once('../../Model/admin/post.php');

$categoryModel = new categoryModel;

$postModel = new PostModel;

if (isset($_GET['postId'])) {

$postId = $_GET['postId'];

$categories = $categoryModel->categoryList(); /*lấy toàn bộ chuyên mục trong bảng categories*/

$postOld = $postModel->getPost($postId);

require('pages/post/edit.php');

}

}

}

Hiển thị dữ liệu cũ trong form chỉnh sửa bài viết, khi đó file View/admin/pages/post/edit.php trở thành:

<div class="content-wrapper" style="min-height: 353px;">

<div class="content-header">

<div class="container-fluid">

<div class="row mb-2">

<div class="col-sm-6">

<h1 class="m-0 text-dark">Sửa bài viết</h1>

</div><!-- /.col -->

<div class="col-sm-6">

<ol class="breadcrumb float-sm-right">

<li class="breadcrumb-item"><a href="#">Bài viết</a></li>

<li class="breadcrumb-item active">Admin</li>

</ol>

</div>

</div>

</div>

</div>

<section class="content">

<div class="container-fluid">

<form method="post" enctype="multipart/form-data">

<div class="card-div">

<div class="form-group">

<label>Tiêu đề</label>

<input value="<?=$postOld['title']?>" type="text" required="required" name="title" class="form-control" placeholder="Tên chuyên mục">

</div>

<div class="form-group">

<label>Chuyên mục</label>

<select name="category_id" class="form-control select2">

<?php

foreach ($categories as $category) {?>

<option <?php if ($category['id'] == $postOld['category_id']) {echo "selected";} ?> value="<?=$category['id']?>">

<?=$category['name']?>

</option>

<?php }

?>

<option>Thể thao</option>

</select>

</div>

<div class="form-group">

<label>Ảnh cũ</label><br>

<img width="200px" src="../../Public/upload/posts/<?=$postOld['image']?>">

<input type="hidden" value="<?=$postOld['image']?>" name="iamge_old">

</div>

<div class="form-group">

<label for="exampleInputFile">Chọn ảnh</label>

<div class="input-group">

<div class="custom-file">

<input type="file" name="image" class="custom-file-input" id="exampleInputFile">

<label class="custom-file-label" for="exampleInputFile">Chọn ảnh</label>

</div>

</div>

</div>

<div class="form-group">

<label>Tóm tắt</label>

<textarea class="textarea" name="summary" required="required" placeholder="Place some text here"

style="width: 100%; height: 500px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;"><?=$postOld['summary']?></textarea>

</div>

<div class="form-group">

<label>Nội dung</label>

<textarea required="required" name="content" class="textarea" placeholder="Place some text here"

style="width: 100%; height: 500px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;"><?=$postOld['content']?></textarea>

</div>

<button type="submit" name="editPost" class="btn btn-primary">Hoàn thành</button>

</div>

</form>

</div>

</section>

</div>

  • Viết code chức năng sửa bài viết

Sau khi đã làm xong các bước ở trên, cuối cùng chúng ta bắt tay vào làm chức năng sửa bài viết. Viết hàm editPost  bên Model, hàm này có chức năng chỉnh sửa bài viết trong file Model/admin/post.php:

public function editPost($id, $title, $slug, $summary, $content, $categoryId, $image)

{

$title = $this->db->conn->real_escape_string($title);

$slug = $this->db->conn->real_escape_string($slug);

$summary = $this->db->conn->real_escape_string($summary);

$content = $this->db->conn->real_escape_string($content);

$sql = "UPDATE posts SET title = '$title',

slug = '$slug',

summary = '$summary',

content = '$content',

category_id = '$categoryId',

image = '$image'

WHERE id = $id

";

return $this->db->conn->query($sql);

}

Bên Controller thực hiện lấy giữ từ form, khi đó file Controller/admin/editPost.php trở thành:

<?php

class EditPost {

public function __construct()

{

require_once('../../Model/admin/category.php');

require_once('../../Model/admin/post.php');

$categoryModel = new categoryModel;

$postModel = new PostModel;

if (isset($_GET['postId'])) {

$postId = $_GET['postId'];

$categories = $categoryModel->categoryList(); /*lấy toàn bộ chuyên mục trong bảng categories*/

$postOld = $postModel->getPost($postId);

if (isset($_POST['editPost'])) {

$title = $_POST['title'];

$slug = changeTitle($title);

$summary = $_POST['summary'];

$content = $_POST['content'];

$categoryId = $_POST['category_id'];

/**

* Nếu không chọn ảnh thì lấy tên ảnh trong input có name là image_old

* Ngược lại thì lấy tên ảnh theo $slug và lưu vào Public/upload/post

* Tiến hành sửa bài viết bằng hàm editPost bên Model

* @var array

*/

if (isset($_FILES['image']) && $_FILES['image']['error'] > 0) {

$image = $_POST['image_old'];

} else {

$ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);

$image = $slug . '.' . $ext;

move_uploaded_file($_FILES['image']['tmp_name'], '../../Public/upload/posts/' . $image);

}

$postModel->editPost($postId, $title, $slug, $summary, $content, $categoryId, $image);

}

require('pages/post/edit.php');

}

}

}

  • Viết code chức năng xóa bài viết

Đối với trang xóa dữ liệu, chúng ta cũng không cần phải xử lý quá nhiều. Bởi nhiệm vụ của chúng chỉ đơn giản là xóa đi những dòng trong bảng.

Và thực thi hàm deletePost trong file Model/admin/post.php:

public function deletePost($postId){

$sql = "DELETE FROM posts WHERE id = $postId";

return $this->db->conn->query($sql);

}

Tiếp theo bên Controller, gọi hàm deletePost để thực hiện xóa bài viết, tạo file Controller/admin/deletePost.php và thưc thi các lệnh sau:

<?php

class DeletePost {

public function __construct()

{

require_once('../../Model/admin/post.php');

$postModel = new PostModel();

if (isset($_GET['postId'])) {

$postId = $_GET['postId'];

$postModel->deletePost($postId);

header('Location: ?controller=listPost');

}

require('pages/category/add.php');

}

}