Bài 13: PHP trang tin tức - Các chức năng của bài viết admin (tiếp theo)

DOWNLOAD

Hello, chào mừng các bạn đã quay trở lại với series hướng dẫn dựng trang tin tức bằng PHP. Trong bài trước, chúng ta đã khởi tạo table và xây dựng chức năng thêm bài viết rồi. Hôm nay, mình sẽ hướng dẫn các bạn làm các chức năng còn lại, bài này hơi dài nên các bạn chú ý theo dõi từng bước nhé! Bây giờ chúng ta bắt tay vào việc thôi.

1. Hiển thị danh sách bài viết

Thiết lập url phân trang bài viết

Các bạn thiết lập tại file .htaccess, mở file này lên và copy đoạn code sau:

# Url phân trang bài viết
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?tab=$1&page=$2
RewriteRule ^([a-zA-Z0-9_-]+)&page=([a-zA-Z0-9_-]+)$ index.php?tab=$1&page=$2

Như mình đã đề cập ở bài trước, phần hiển thị danh sách bài viết sẽ bao gồm:

  • Danh sách bài viết (Hiển thị theo bài viết của tác giả, ngoại trừ admin)
  • Phân trang (theo phương thức GET trên thanh address)
  • Tìm kiếm (theo ID, tiêu đề, url)

Xây dựng template

Các bạn mở file admin/templates/posts.php lên và copy nội dung này bên dưới dòng // Content danh sách bài viết:

// Nếu là admin thì lấy toàn bộ bài viết
if ($data_user['position'] == '1') {
    $sql_get_list_post = "SELECT * FROM posts ORDER BY id_post DESC";
// Nếu là tác giả thì chỉ lấy những bài thuộc sở hữu
} else {
    $sql_get_list_post = "SELECT * FROM posts WHERE author_id = '$data_user[id_acc]' ORDER BY id_post DESC";
}
// Nếu có bài viết
if ($db->num_rows($sql_get_list_post))
{
    // Lấy số trang
    if (isset($_GET['page'])) {
        $current_page = trim(htmlspecialchars(addslashes($_GET['page']))); 
    } else {
        $current_page = '';
    }

    $limit = 10; // Giới hạn số bài viết trong 1 trang
    $total_page = ceil($db->num_rows($sql_get_list_post) / $limit); // Tổng trang
    $start = ($current_page - 1) * $limit; // Vị trí bắt đầu lấy trang

    // Nếu số trang hiện tại > tổng trang
    if ($current_page > $total_page) {
        new Redirect($_DOMAIN . 'posts&page=' . $total_page); // Tới số trang lớn nhất
    // Nếu số trang hiện tại < 1
    } else if ($current_page < 1){
        new Redirect($_DOMAIN . 'posts&page=1'); // Tới trang đầu tiên
    }   

    // Form tìm kiếm
    echo 
    '
        <p>
            <form method="POST" id="formSearchPost" onsubmit="return false;">
                <div class="input-group">         
                    <input type="text" class="form-control" id="kw_search_post" placeholder="Nhập ID, tiêu đề, slug ...">
                    <span class="input-group-btn">
                        <button class="btn btn-primary" type="submit"><i class="glyphicon glyphicon-search"></i></button>
                    </span>
                </div>
            </form>
        </p>
    ';

    echo 
    '
        <div class="table-responsive" id="list_post">
            <table class="table table-striped list">
                <tr>
                    <td><input type="checkbox"></td>
                    <td><strong>ID</strong></td>
                    <td><strong>Tiêu đề</strong></td>
                    <td><strong>Trạng thái</strong></td>
                    <td><strong>Chuyên mục</strong></td>
                    <td><strong>Lượt xem</strong></td>
    ';

    // Nếu tài khoản là admin
    if ($data_user['position'] == '1') {
        echo '<td><strong>Tác giả</strong></td>';
    }

    echo '
                    <td><strong>Tools</strong></td>
                </tr>
    ';

    
    // Nếu là admin thì lấy toàn bộ bài viết
    if ($data_user['position'] == '1') {
        $sql_get_list_post_limit = "SELECT * FROM posts ORDER BY id_post DESC LIMIT $start, $limit";
    // Nếu là tác giả thì chỉ lấy những bài thuộc sở hữu
    } else {
        $sql_get_list_post_limit = "SELECT * FROM posts WHERE author_id = '$data_user[id_acc]' ORDER BY id_post DESC LIMIT $start, $limit";
    }
    // In danh sách bài viết
    foreach ($db->fetch_assoc($sql_get_list_post_limit, 0) as $key => $data_post) 
    {
        // Trạng thái bài viết
        if ($data_post['status'] == 0) {
            $stt_post = '<label class="label label-warning">Ẩn</label>';
        } else if ($data_post['status'] == 1) {
            $stt_post = '<label class="label label-success">Xuấn bản</label>';
        }

        // Chuyên mục bài viết
        $cate_post = '';
        $sql_check_id_cate_1 = "SELECT label, id_cate FROM categories WHERE id_cate = '$data_post[cate_1_id]' AND type = '1'";
        if ($db->num_rows($sql_check_id_cate_1)) {
            $data_cate_1 = $db->fetch_assoc($sql_check_id_cate_1, 1);
            $cate_post .= $data_cate_1['label'];
        } else {
            $cate_post .= '<span class="text-danger">Lỗi</span>';
        }

        $sql_check_id_cate_2 = "SELECT label, id_cate FROM categories WHERE id_cate = '$data_post[cate_2_id]' AND type = '2'";
        if ($db->num_rows($sql_check_id_cate_2)) {
            $data_cate_2 = $db->fetch_assoc($sql_check_id_cate_2, 1);
            $cate_post .= ', ' . $data_cate_2['label'];
        } else {
            $cate_post .= ', <span class="text-danger">Lỗi</span>';
        }

        $sql_check_id_cate_3 = "SELECT label, id_cate FROM categories WHERE id_cate = '$data_post[cate_3_id]' AND type = '3'";
        if ($db->num_rows($sql_check_id_cate_3)) {
            $data_cate_3 = $db->fetch_assoc($sql_check_id_cate_3, 1);
            $cate_post .= ', ' . $data_cate_3['label'];
        } else {
            $cate_post .= ', <span class="text-danger">Lỗi</span>';
        }

        // Tác giả bài viết
        $sql_get_author = "SELECT display_name FROM accounts WHERE id_acc = '$data_post[author_id]'";
        if ($db->num_rows($sql_get_author)) {
            $data_author = $db->fetch_assoc($sql_get_author, 1);
            $author_post = $data_author['display_name'];
        } else {
            $author_post = '<span class="text-danger">Lỗi</span>';
        }

        echo 
        '
            <tr>
                <td><input type="checkbox" name="id_post[]" value="' . $data_post['id_post'] .'"></td>
                <td>' . $data_post['id_post'] . '</td>
                <td style="width: 30%;"><a href="' . $_DOMAIN . 'posts/edit/' . $data_post['id_post'] . '">' . $data_post['title'] . '</a></td>
                <td>' . $stt_post . '</td>
                <td>' . $cate_post . '</td>
                <td>' . $data_post['view'] . '</td>
        ';

        // Tác giả bài viết
        if ($data_user['position'] == '1') {
            echo '<td>' . $author_post . '</td>';
        }

        echo '
                <td>
                    <a href="' . $_DOMAIN . 'posts/edit/' . $data_post['id_post'] .'" class="btn btn-primary btn-sm">
                        <span class="glyphicon glyphicon-edit"></span>
                    </a>
                    <a class="btn btn-danger btn-sm del-post-list" data-id="' . $data_post['id_post'] . '">
                        <span class="glyphicon glyphicon-trash"></span>
                    </a>
                </td>
            </tr>
        ';
    }

    echo 
    '
            </table>
    ';

    // Nút phân trang
    echo '<div class="btn-group" id="paging_post">';
    // Nếu trang hiện tại > 1 và tổng trang > 1 thì hiển thị nút prev
    if ($current_page > 1 && $total_page > 1){
        echo '<a class="btn btn-default" href="' . $_DOMAIN . 'posts&page=' . ($current_page - 1) . '"><span class="glyphicon glyphicon-chevron-left"></span> Prev</a>';
    }
     
    // In số nút trang
    for ($i = 1; $i <= $total_page; $i++){
        // Nếu trùng với trang hiện tại thì active
        if ($i == $current_page){
            echo '<a class="btn btn-default active">' . $i . '</a>';
        // Ngược lại
        } else {
            echo '<a class="btn btn-default" href="' . $_DOMAIN . 'posts&page=' . $i . '">' . $i . '</a>';
        }
    }
     
    // Nếu trang hiện tại < tổng số trang > 1 thì hiển thị nút next
    if ($current_page < $total_page && $total_page > 1){
        echo '<a class="btn btn-default" href="' . $_DOMAIN . 'posts&page=' . ($current_page + 1) . '">Next <span class="glyphicon glyphicon-chevron-right"></span></a>';
    }
    echo '<br><br><br></div>';

    echo '
        </div>
    ';
}
// Nếu không có bài viết
else
{
    echo '<br><br><div class="alert alert-info">Chưa có bài viết nào.</div>';
}
Bên trong mình chú thích từng phần rất kỹ rồi, còn về phần phân trang, bạn nào chưa hiểu thì tìm hiểu bài Thuật toán phân trang với PHP và MySQL ngay tại blog luôn nhé!

Các bạn chạy lại xem kết quả:

Có lẽ các bạn đang thắc mắc tại sao chỗ chuyên mục lại "Lỗi" nhiều đến thế phải không? Vì ở chức năng tạo bài viết, chúng ta chưa thiết lập chuyên mục cho chúng, mà trong code danh sách này mình có thêm bước kiểm tra sự tồn tại của các chuyên mục. Vì thế hiện tại bây giờ như thế là OK, để khắc phục chúng ta sẽ tìm hiển ở bước viết chức năng chỉnh sửa bài viết nhé!

Chức năng tìm kiếm bài viết

Phần template mình đã xây dựng ở trên rồi, giờ chúng ta chỉ cần thực hiện hai bước ở dưới nữa thôi. Ở đây mình sẽ viết chức năng này bằng Ajax và PHP.

Viết Ajax gửi dữ liệu

Các bạn mở file admin/js/form.js và dán nội dung này vào:

// Tìm kiếm bài viết
$('#formSearchPost button').on('click', function() {
	$kw_search_post = $('#kw_search_post').val();

	if ($kw_search_post != '') {
		$.ajax({
			url : $_DOMAIN + 'posts.php',
			type : 'POST',
			data : {
				kw_search_post : $kw_search_post,
				action : 'search_post'
			}, success : function(data) {
				$('#list_post').html(data);
				$('#paging_post').hide();
			}
		});
	}
});

Viết PHP xử lý dữ liệu

Để xử lý tìm kiếm mình sẽ sử dụng file admin/posts.php luôn nên các bạn mở file này lên và chèn đoạn code này bên dưới dòng // Tải chuyên mục trong chỉnh sửa bài viết:

// Tìm kiếm bài viết
else if ($action == 'search_post')
{
	$kw_search_post = trim(htmlspecialchars(addslashes($_POST['kw_search_post'])));

	if ($kw_search_post != '')
	{
		$sql_search_post = "SELECT * FROM posts WHERE 
			id_post LIKE '%$kw_search_post%' OR
			title LIKE '%$kw_search_post%' OR
			slug LIKE '%$kw_search_post%'
			ORDER BY id_post DESC
		";

		// Nếu có kết quả
		if ($db->num_rows($sql_search_post)) 
		{
			echo 
		    '
		    	<table class="table table-striped list">
		            <tr>
		                <td><input type="checkbox"></td>
		                <td><strong>ID</strong></td>
		                <td><strong>Tiêu đề</strong></td>
		                <td><strong>Trạng thái</strong></td>
		                <td><strong>Chuyên mục</strong></td>
		                <td><strong>Lượt xem</strong></td>
		    ';

		    // Nếu tài khoản là admin
		    if ($data_user['position'] == '1') {
		        echo '<td><strong>Tác giả</strong></td>';
		    }

		    echo '
		                    <td><strong>Tools</strong></td>
		                </tr>
		    ';

		    // In danh sách kết quả bài viết
		    foreach ($db->fetch_assoc($sql_search_post, 0) as $key => $data_post) 
		    {
		        // Trạng thái bài viết
		        if ($data_post['status'] == 0) {
		            $stt_post = '<label class="label label-warning">Ẩn</label>';
		        } else if ($data_post['status'] == 1) {
		            $stt_post = '<label class="label label-success">Xuấn bản</label>';
		        }

		        // Chuyên mục bài viết
		        $cate_post = '';
		        $sql_check_id_cate_1 = "SELECT label, id_cate FROM categories WHERE id_cate = '$data_post[cate_1_id]' AND type = '1'";
		        if ($db->num_rows($sql_check_id_cate_1)) {
		            $data_cate_1 = $db->fetch_assoc($sql_check_id_cate_1, 1);
		            $cate_post .= $data_cate_1['label'];
		        } else {
		            $cate_post .= '<span class="text-danger">Lỗi</span>';
		        }

		        $sql_check_id_cate_2 = "SELECT label, id_cate FROM categories WHERE id_cate = '$data_post[cate_2_id]' AND type = '2'";
		        if ($db->num_rows($sql_check_id_cate_2)) {
		            $data_cate_2 = $db->fetch_assoc($sql_check_id_cate_2, 1);
		            $cate_post .= ', ' . $data_cate_2['label'];
		        } else {
		            $cate_post .= ', <span class="text-danger">Lỗi</span>';
		        }

		        $sql_check_id_cate_3 = "SELECT label, id_cate FROM categories WHERE id_cate = '$data_post[cate_3_id]' AND type = '3'";
		        if ($db->num_rows($sql_check_id_cate_3)) {
		            $data_cate_3 = $db->fetch_assoc($sql_check_id_cate_3, 1);
		            $cate_post .= ', ' . $data_cate_3['label'];
		        } else {
		            $cate_post .= ', <span class="text-danger">Lỗi</span>';
		        }

		        // Tác giả bài viết
		        $sql_get_author = "SELECT display_name FROM accounts WHERE id_acc = '$data_post[author_id]'";
		        if ($db->num_rows($sql_get_author)) {
		            $data_author = $db->fetch_assoc($sql_get_author, 1);
		            $author_post = $data_author['display_name'];
		        } else {
		            $author_post = '<span class="text-danger">Lỗi</span>';
		        }

		        echo 
		        '
		            <tr>
		                <td><input type="checkbox" name="id_post[]" value="' . $data_post['id_post'] .'"></td>
		                <td>' . $data_post['id_post'] . '</td>
		                <td style="width: 30%;"><a href="' . $_DOMAIN . 'posts/edit/' . $data_post['id_post'] . '">' . $data_post['title'] . '</a></td>
		                <td>' . $stt_post . '</td>
		                <td>' . $cate_post . '</td>
		                <td>' . $data_post['view'] . '</td>
		        ';

		        // Tác giả bài viết
		        if ($data_user['position'] == '1') {
		            echo '<td>' . $author_post . '</td>';
		        }

		        echo '
		                <td>
		                    <a href="' . $_DOMAIN . 'posts/edit/' . $data_post['id_post'] .'" class="btn btn-primary btn-sm">
		                        <span class="glyphicon glyphicon-edit"></span>
		                    </a>
		                    <a class="btn btn-danger btn-sm del-post-list" data-id="' . $data_post['id_post'] . '">
		                        <span class="glyphicon glyphicon-trash"></span>
		                    </a>
		                </td>
		            </tr>
		        ';
		    }
    		echo '</table>';
		} 
		// Ngược lại không có kết quả
		else
		{
			echo '<div class="alert alert-info">Không tìm thấy kết quả nào cho từ khoá <strong>' . $kw_search_post . '</strong>.</div>';
		}
	}
}
Giờ các bạn chạy lại và test chức năng tìm kiếm xem có hoạt động không nhé!

2. Chỉnh sửa bài viết

Thư viện CKEditor

Đây là một thư viện editor cho web, nó có các chức năng gần giống như Word để giúp trong quá trình viết bài. Để tải thư viện này các bạn truy cập đường dẫn http://ckeditor.com/download, mình khuyên các bạn nên chọn verison Standdard Package vì nó có đầy đủ chức năng cho ứng dụng của mình rồi, không cần verison Full Package cho nặng hệ thống. 

Sau khi download xong, các bạn giải nén file trong thư mục admin, chúng ta sẽ được folder admin/ckeditor.

Tiếp theo các bạn mở file admin/includes/footer.php lên và chèn đoạn code này bên dưới dòng <script src="<?php echo $_DOMAIN; ?>js/form.js"></script>:

<!-- Liên kết thư viện CKEditor -->
<script src="<?php echo $_DOMAIN; ?>ckeditor/ckeditor.js"></script>
<script>
	config = {};
	config.entities_latin = false;
	config.language = "vi";
	CKEDITOR.replace("body_edit_post", config);
</script>
Trong đoạn code này các bạn chỉ chú ý cho mình cái body_edit_post, đây là id để thiết lập CKEditor, sau này để biến textarea thành CKEditor các bạn chỉ cần truyền id body_edit_post vào là Ok.

Xây dựng template

Các bạn mở file admin/templates/posts.php lên và dán nội dung này bên dưới dòng // Content chỉnh sửa bài viết:

$sql_get_data_post = "SELECT * FROM posts WHERE id_post = '$id'";
$data_post = $db->fetch_assoc($sql_get_data_post, 1);
echo 
'
    <p class="form-edit-post">
        <form method="POST" id="formEditPost" data-id="' . $id . '" onsubmit="return false;">
            <div class="form-group">
                <label>Trạng thái bài viết</label>
';

// Trạng thái bài viết
// Nếu đã xuất bản
if ($data_post['status'] == '1') {
    echo '
        <div class="radio">
            <label>
                <input type="radio" name="stt_edit_post" value="1" checked> Xuất bản
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" name="stt_edit_post" value="0"> Ẩn
            </label>
        </div>
    ';
// Nếu đang ẩn
} else if ($data_post['status'] == '0') {
    echo '
        <div class="radio">
            <label>
                <input type="radio" name="stt_edit_post" value="1"> Xuất bản
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" name="stt_edit_post" value="0" checked> Ẩn
            </label>
        </div>
    ';
}

echo '
            </div>
            <div class="form-group">
                <label>Tiêu đề bài viết</label>
                <input type="text" class="form-control title" value="' . $data_post['title'] . '" id="title_edit_post">
            </div>
            <div class="form-group">
                <label>Slug bài viết</label>
                <input type="text" class="form-control slug" value="' . $data_post['slug'] . '" id="slug_edit_post">
            </div>
            <div class="form-group">
                <label>Url thumbnail</label>
                <input type="text" class="form-control" value="' . $data_post['url_thumb'] . '" id="url_thumb_edit_post">
            </div>
            <div class="form-group">
                <label>Mô tả bài viết</label>
                <textarea id="desc_edit_post" class="form-control">' . $data_post['desc'] . '</textarea>
            </div>
            <div class="form-group">
                <label>Từ khoá bài viết</label>
                <input type="text" class="form-control" value="' . $data_post['keywords'] . '" id="keywords_edit_post">
            </div>
            <div class="form-group cate_post_1">
                <label>Chuyên mục lớn</label>
                <select class="form-control" id="cate_post_1">
';

// Tải chuyên mục lớn bài viết
$sql_get_cate_post_1 = "SELECT label, id_cate FROM categories WHERE type = '1'";
if ($db->num_rows($sql_get_cate_post_1)) {
    if ($data_post['cate_1_id'] == '0') {
        echo '<option value="">Vui lòng chọn chuyên mục</option>';
    }
    foreach ($db->fetch_assoc($sql_get_cate_post_1, 0) as $key => $data_cate_1) {
        if ($data_cate_1['id_cate'] == $data_post['cate_1_id']) {
            echo '<option value="' . $data_cate_1['id_cate'] . '" selected>' . $data_cate_1['label'] . '</option>';
        } else {
            echo '<option value="' . $data_cate_1['id_cate'] . '">' . $data_cate_1['label'] . '</option>';
        }
    }
} else {
    echo '<option value="">Chưa có chuyên mục lớn nào</option>';
}

echo '

                </select>
            </div>
            <div class="form-group cate_post_2">
                <label>Chuyên mục vừa</label>
                <select class="form-control" id="cate_post_2">
';

// Tải chuyên mục vừa bài viết
$sql_get_cate_post_2 = "SELECT label, id_cate FROM categories WHERE type = '2' AND parent_id = '$data_post[cate_1_id]'";
if ($db->num_rows($sql_get_cate_post_2)) {
    if ($data_post['cate_2_id'] == '0') {
        echo '<option value="">Vui lòng chọn chuyên mục</option>';
    }
    foreach ($db->fetch_assoc($sql_get_cate_post_2, 0) as $key => $data_cate_2) {
        if ($data_cate_2['id_cate'] == $data_post['cate_2_id']) {
            echo '<option value="' . $data_cate_2['id_cate'] . '" selected>' . $data_cate_2['label'] . '</option>';
        } else {
            echo '<option value="' . $data_cate_2['id_cate'] . '">' . $data_cate_2['label'] . '</option>';
        }
    }
} else {
    echo '<option value="">Chưa có chuyên mục vừa nào</option>';
}

echo '

                </select>
            </div>
            <div class="form-group cate_post_3">
                <label>Chuyên mục nhỏ</label>
                <select class="form-control" id="cate_post_3">
';

// Tải chuyên mục vừa bài viết
$sql_get_cate_post_3 = "SELECT label, id_cate FROM categories WHERE type = '3' AND parent_id = '$data_post[cate_2_id]'";
if ($db->num_rows($sql_get_cate_post_3)) {
    if ($data_post['cate_3_id'] == '0') {
        echo '<option value="">Vui lòng chọn chuyên mục</option>';
    }
    foreach ($db->fetch_assoc($sql_get_cate_post_3, 0) as $key => $data_cate_3) {
        if ($data_cate_3['id_cate'] == $data_post['cate_3_id']) {
            echo '<option value="' . $data_cate_3['id_cate'] . '" selected>' . $data_cate_3['label'] . '</option>';
        } else {
            echo '<option value="' . $data_cate_3['id_cate'] . '">' . $data_cate_3['label'] . '</option>';
        }
    }
} else {
    echo '<option value="">Chưa có chuyên mục nhỏ nào</option>';
}

echo '

                </select>
            </div>
            <div class="form-group">
                <label>Nội dung bài viết</label>
                <textarea id="body_edit_post" class="form-control">' . $data_post['body'] . '</textarea>
            </div>
            <div class="form-group">
                <button type="submit" class="btn btn-primary">Lưu thay đổi</button>
            </div>
            <div class="alert alert-danger hidden"></div>
        </form>
    </p>
';
Sau đó các bạn reload lại để xem kết quả nhé!

Viết Ajax gửi dữ liệu

Load chuyên mục bài viết

Các bạn mở file admin/js/form.js lên và pase đoạn code này vào:

// Tải chuyên mục vừa và nhỏ trong chỉnh sửa bài viết
$('#cate_post_1').on('change', function() {
	$parent_id = $(this).val();

	$.ajax({
		url : $_DOMAIN + 'posts.php',
		type : 'POST',
		data : {
			parent_id : $parent_id,
			action : 'load_cate_2'
		}, success : function(data) {
			$('#cate_post_2').html(data);

			// Sau khi tải xong chuyên mục vừa sẽ tải chuyên mục nhỏ 
			$parent_id = $('#cate_post_2').val();

			$.ajax({
				url : $_DOMAIN + 'posts.php',
				type : 'POST',
				data : {
					parent_id : $parent_id,
					action : 'load_cate_3'
				}, success : function(data) {
					$('#cate_post_3').html(data);
				}
			});
		}
	});
});

// Tải chuyên mục nhỏ trong chỉnh sửa bài viết
$('#cate_post_2').on('change', function() {
	$parent_id = $(this).val();

	$.ajax({
		url : $_DOMAIN + 'posts.php',
		type : 'POST',
		data : {
			parent_id : $parent_id,
			action : 'load_cate_3'
		}, success : function(data) {
			$('#cate_post_3').html(data);
		}
	});
});

Chỉnh sửa bài viết

Chèn tiếp đoạn code này để thực thị gửi dữ liệu chỉnh sửa bài viết:

// Chỉnh sửa bài viết
$('#formEditPost button').on('click', function() {
	$id_post = $('#formEditPost').attr('data-id');
	$stt_edit_post = $('#formEditPost input[name="stt_edit_post"]:radio:checked').val();
	$title_edit_post = $('#title_edit_post').val();
	$slug_edit_post = $('#slug_edit_post').val();
	$url_thumb_edit_post = $('#url_thumb_edit_post').val();
	$desc_edit_post = $('#desc_edit_post').val();
	$keywords_edit_post = $('#keywords_edit_post').val();
	$cate_1_edit_post = $('#cate_post_1').val();
	$cate_2_edit_post = $('#cate_post_2').val();
	$cate_3_edit_post = $('#cate_post_3').val();
	$body_edit_post = CKEDITOR.instances['body_edit_post'].getData();

	if ($stt_edit_post == '' || $title_edit_post == '' || $slug_edit_post == '' || $cate_1_edit_post == '' || $cate_2_edit_post == '' || $cate_3_edit_post == '' || $body_edit_post == '') 
	{
		$('#formEditPost .alert').removeClass('hidden');
		$('#formEditPost .alert').html('Vui lòng điền đầy đủ thông tin.');
	} 
	else
	{
		$.ajax({
			url : $_DOMAIN + 'posts.php',
			type : 'POST',
			data : {
				id_post : $id_post,
				stt_edit_post : $stt_edit_post,
				title_edit_post : $title_edit_post,
				slug_edit_post : $slug_edit_post,
				url_thumb_edit_post : $url_thumb_edit_post,
				keywords_edit_post : $keywords_edit_post,
				desc_edit_post : $desc_edit_post,
				cate_1_edit_post : $cate_1_edit_post,
				cate_2_edit_post : $cate_2_edit_post,
				cate_3_edit_post : $cate_3_edit_post,
				body_edit_post : $body_edit_post,
				action : 'edit_post'
			}, success : function(data) {
				$('#formEditPost .alert').removeClass('hidden');
				$('#formEditPost .alert').html(data);
			}, error : function() {
				$('#formEditPost .alert').removeClass('hidden');
				$('#formEditPost .alert').html('Đã có lỗi xảy ra, hãy thử lại sau.');
			}
		});
	}
});
Trong đó có dòng $body_edit_post = CKEDITOR.instances['body_edit_post'].getData();, dòng này sẽ lấy dữ liệu trong textarea CKEditor tương ứng với id bên trong cặp [].

Viết PHP xử lý dữ liệu

Load chuyên mục bài viết

File admin/posts.php sẽ đảm nhận việc này, các bạn mở nó lên và chèn đoạn code này bên dưới dòng // Tải chuyên mục trong chỉnh sửa bài viết:

// Chuyên mục vừa
else if ($action == 'load_cate_2')
{
	$parent_id = trim(htmlspecialchars(addslashes($_POST['parent_id'])));

	$sql_get_cate_2 = "SELECT id_cate, label FROM categories WHERE type = '2' AND parent_id = '$parent_id'";
	if ($db->num_rows($sql_get_cate_2)) {
		foreach ($db->fetch_assoc($sql_get_cate_2, 0) as $key => $data_cate_2) {
			echo '<option value="' . $data_cate_2['id_cate'] . '">' . $data_cate_2['label'] . '</option>';
		}
	} else {
		echo '<option value="">Chưa có chuyên mục vừa nào</option>';
	}
}
// Chuyên mục nhỏ
else if ($action == 'load_cate_3')
{
	$parent_id = trim(htmlspecialchars(addslashes($_POST['parent_id'])));

	$sql_get_cate_3 = "SELECT id_cate, label FROM categories WHERE type = '3' AND parent_id = '$parent_id'";
	if ($db->num_rows($sql_get_cate_3)) {
		foreach ($db->fetch_assoc($sql_get_cate_3, 0) as $key => $data_cate_3) {
			echo '<option value="' . $data_cate_3['id_cate'] . '">' . $data_cate_3['label'] . '</option>';
		}
	} else {
		echo '<option value="">Chưa có chuyên mục nhỏ nào</option>';
	}
}

// Chỉnh sửa bài viết

Chỉnh sửa bài viết

Các bạn copy đoạn code này và dán bên dưới dòng // Chỉnh sửa bài viết:

else if ($action == 'edit_post')
{
	// Xử lý các giá trị
	$id_post = trim(htmlspecialchars(addslashes($_POST['id_post'])));
	$stt_edit_post = trim(htmlspecialchars(addslashes($_POST['stt_edit_post'])));
	$title_edit_post = trim(htmlspecialchars(addslashes($_POST['title_edit_post'])));
	$slug_edit_post = trim(htmlspecialchars(addslashes($_POST['slug_edit_post'])));
	$url_thumb_edit_post = trim(htmlspecialchars(addslashes($_POST['url_thumb_edit_post'])));
	$desc_edit_post = trim(htmlspecialchars(addslashes($_POST['desc_edit_post'])));
	$keywords_edit_post = trim(htmlspecialchars(addslashes($_POST['keywords_edit_post'])));
	$cate_1_edit_post = trim(htmlspecialchars(addslashes($_POST['cate_1_edit_post'])));
	$cate_2_edit_post = trim(htmlspecialchars(addslashes($_POST['cate_2_edit_post'])));
	$cate_3_edit_post = trim(htmlspecialchars(addslashes($_POST['cate_3_edit_post'])));
	$body_edit_post = trim(htmlspecialchars(addslashes($_POST['body_edit_post'])));

	// Các biến xử lý thông báo
	$show_alert = '<script>$("#formEditPost .alert").removeClass("hidden");</script>';
	$hide_alert = '<script>$("#formEditPost .alert").addClass("hidden");</script>';
	$success = '<script>$("#formEditPost .alert").attr("class", "alert alert-success");</script>';

	// Kiểm tra id bài viết
	$sql_check_id_post = "SELECT id_post FROM posts WHERE id_post = '$id_post'";

	// Nếu các giá trị rỗng
	if ($stt_edit_post == '' || $title_edit_post == '' || $slug_edit_post == '' || $cate_1_edit_post == '' || $cate_2_edit_post == '' || $cate_3_edit_post == '' || $body_edit_post == '') 
	{
		echo $show_alert.'Vui lòng điền đầy đủ thông tin.';
	} 
	else if (!$db->num_rows($sql_check_id_post))
	{
		echo $show_alert.'Đã có lỗi xảy ra, vui lòng thử lại.';
	}
	// Kiểm tra url ảnh
	else if ($url_thumb_edit_post != '' && filter_var($url_thumb_edit_post, FILTER_VALIDATE_URL) === false)
	{
		echo $show_alert.'Vui lòng nhập url thumbnail hợp lệ.';
	}
	else
	{
		// Sửa bài viết
		$sql_edit_post = "UPDATE posts SET
			status = '$stt_edit_post',
			title = '$title_edit_post',
			slug = '$slug_edit_post',
			url_thumb = '$url_thumb_edit_post',
			descr = '$desc_edit_post',
			keywords = '$keywords_edit_post',
			cate_1_id = '$cate_1_edit_post',
			cate_2_id = '$cate_2_edit_post',
			cate_3_id = '$cate_3_edit_post',
			body = '$body_edit_post'
			WHERE id_post = '$id_post';
		";
		$db->query($sql_edit_post);
		$db->close();
		echo $show_alert.$success.'Chỉnh sửa bài viết thành công.';
		new Redirect($_DOMAIN.'posts/edit/'.$id_post);
	}
}

// Xoá bài viết
Giờ các bạn tải lại trang và chạy thử nhé!

3. Xoá bài viết

Cũng như các chức năng khác, xoá bài viết cũng chia làm hai loại: xoá nhiều bài viết và xoá bài viết chỉ định.

Xoá nhiều bài viết

Viết Ajax gửi dữ liệu

Các bạn mở file admin/js/form.js lên và copy đoạn code này vào:

// Xoá nhiều bài viết cùng lúc
$('#del_post_list').on('click', function() {
	$confirm = confirm('Bạn có chắc chắn muốn xoá các bài viết đã chọn không?');
	if ($confirm == true)
	{
		$id_post = [];

		$('#list_post input[type="checkbox"]:checkbox:checked').each(function(i) {
			$id_post[i] = $(this).val();
		});

		if ($id_post.length === 0)
		{
			alert('Vui lòng chọn ít nhất một bài viết.');
		}
		else
		{
			$.ajax({
				url : $_DOMAIN + 'posts.php',
				type : 'POST',
				},
				data : {
					id_post : $id_post,
					action : 'delete_post_list'
				success : function(data) {
					location.reload();
				}, error : function() {
					alert('Đã có lỗi xảy ra, hãy thử lại.');
				}
			});
		}
	}
	else
	{
		return false;
	}
});
Viết PHP xử lý dữ liệu

Tiếp theo mở file admin/posts.php lên và dán đoạn code này dưới dòng // Xoá bài viết để tiến hành xử lý:

// Xoá nhiều bài viết cùng lúc
else if ($action == 'delete_post_list')
{
	foreach ($_POST['id_post'] as $key => $id_post)
	{
		$sql_check_id_post_exist = "SELECT id_post FROM posts WHERE id_post = '$id_post'";
		if ($db->num_rows($sql_check_id_post_exist))
		{
			$sql_delete_post = "DELETE FROM posts WHERE id_post = '$id_post'";
			$db->query($sql_delete_post);
		}
	}	
	$db->close();
}

Xoá bài viết chỉ định

Về phần này sẽ có 2 chỗ : ở trong bảng danh sách và ở trong trang chỉnh sửa của từng bài viết. Vì thế về Ajax gửi dữ liệu chúng ta sẽ viết riêng nhưng về PHP xử lý thì sẽ viết chung.

Viết Ajax gửi dữ liệu

Đầu tiên chúng ta sẽ viết Ajax cho phần xoá ở bảng danh sách trước, các bạn mở file admin/js/form.js lên và copy đoạn code sau:

// Xoá bài viết chỉ định trong bảng danh sách
$('.del-post-list').on('click', function() {
	$confirm = confirm('Bạn có chắc chắn muốn xoá bài viết này không?');
	if ($confirm == true)
	{
		$id_post = $(this).attr('data-id');

		$.ajax({
			url : $_DOMAIN + 'posts.php',
			type : 'POST',
			data : {
				id_post : $id_post,
				action : 'delete_post'
			},
			success : function() {
				location.reload();
			}
		});
	}
	else
	{
		return false;
	}
});
Tiếp theo các bạn sao chép tiếp nội dung này và chèn vào bên dưới để gửi dữ liệu xoá bài viết ở trang chỉnh sửa:

// Xoá bài viết chỉ định trong trang chỉnh sửa
$('#del_post').on('click', function() {
	$confirm = confirm('Bạn có chắc chắn muốn xoá bài viết này không?');
	if ($confirm == true)
	{
		$id_post = $(this).attr('data-id');

		$.ajax({
			url : $_DOMAIN + 'posts.php',
			type : 'POST',
			data : {
				id_post : $id_post,
				action : 'delete_post'
			},
			success : function() {
				location.href = $_DOMAIN + 'posts/';
			}
		});
	}
	else
	{
		return false;
	}
});

Viết PHP xử lý dữ liệu

Đây là đoạn code xử lý dữ liệu cho cả hai cách xoá bài viết chỉ định, các bạn copy vào và chèn tiếp vào bên dưới code xử lý xoá nhiều bài viết cùng lúc ở file admin/posts.php:

// Xoá 1 chuyên mục
else if ($action == 'delete_post')
{		
	$id_post = trim(htmlspecialchars(addslashes($_POST['id_post'])));
	$sql_check_id_post_exist = "SELECT id_post FROM posts WHERE id_post = '$id_post'";
	if ($db->num_rows($sql_check_id_post_exist))
	{
		$sql_delete_post = "DELETE FROM posts WHERE id_post = '$id_post'";
		$db->query($sql_delete_post);
		$db->close();
	}		
}
Giờ các bạn chạy lại và chiêm ngưỡng thành quả thôi!

4. Lời kết

Bài này tương đối là dài nên mình hy vọng các bạn nắm được, nếu có chỗ nào không rõ các bạn cứ comment bên dưới hoặc đăng bài trên group kèm theo link bài viết để dược hỗ trợ nhanh nhất. Qua bài tiếp theo, chúng ta sẽ xây dựng các cài đặt cho ứng dụng. Cảm ơn các bạn đã theo dõi, chúc các bạn thành công!

 

-------------------#####-------------------

Khóa học nên xem

Nguồn: freetuts.net