--------------- <> -----------------
--- KHOA HỌC - CÔNG NGHỆ - GIÁO DỤC - VIỆC LÀM ---
--- Học để đi cùng bà con trên thế giới ---

Tìm kiếm trong Blog

Ngu ngơ học làm web (x29) - CakePHP2 - saveAll(), array->JSON

Tiếp theo của: Ngu ngơ học làm web (x28) - CakePHP2 – findBy(), date(), between
-----

Phần x29. CakePHP2 – saveAll(), array->JSON


Xem (clip số 30b – chickenrainshop):

Đoạn mã tính lại giá trị của mục “Đã giảm” và “Tổng tiền phải trả” khi người dùng nhập mã giảm giá rồi nhưng lại nhập thêm sách:

[action addToCart(), BooksController.php]

$this->Session->write('payment.total', $total);
                                    // kiểm tra xem có mã giảm giá hay không
                                    if ($this->Session->check('payment.coupon')) {
                                                $pay = $total - $total*$this->Session->read('payment.discount')/100;
                                                $this->Session->write('payment.pay', $pay);
                                    }
$this->Flash->success('Đã thêm quyển sách vào trong giỏ hàng!', [

Đoạn mã tính lại giá trị của mục “Đã giảm” và “Tổng tiền phải trả” khi người dùng nhập mã giảm giá rồi nhưng lại cập nhật số lượng sách:

[action quantityUpdate(), BooksController.php]

$this->Session->write('payment.total', $total);
// kiểm tra xem có mã giảm giá hay không
            if ($this->Session->check('payment.coupon')) {
$pay = $total - $total*$this->Session->read('payment.discount')/100;
                        $this->Session->write('payment.pay', $pay);
            }          

Đoạn mã tính lại giá trị của mục “Đã giảm” và “Tổng tiền phải trả” khi người dùng nhập mã giảm giá rồi nhưng lại xóa quyển sách khỏi giỏ hàng:

[action remove(), BooksController.php]

            $total = $this->Tool->arraySum($cart, 'quantity', 'sale_price');
            $this->Session->write('payment.total', $total);
            // kiểm tra xem có mã giảm giá hay không
            if ($this->Session->check('payment.coupon')) {
                        $pay = $total - $total*$this->Session->read('payment.discount')/100;
                        $this->Session->write('payment.pay', $pay);
                        }          
            }
$this->redirect($this->referer());

Xem (clip số 31 – chickenrainshop):

- Label của helper (3":05)

- Sử dụng inputDefaults để bỏ label mặc định cho các input trong form (6":37)

- Tạo một button (7":02)

- Lưu dữ liệu vào database dùng saveAll (15":08) 

- Chuyển chuỗi thành đối tượng JSON (18":20) 

Đoạn mã cho mục “Thanh toán đơn hàng”:

[View\Books\view_cart.ctp]

<li>Mỗi mã giảm giá có mức giảm giá khác nhau và chỉ dùng trong khoảng thời gian quy định.</li>
                                                <li>Chỉ dùng một mã giảm giá khi thanh toán đơn hàng.</li>
                                                <li>Số tiền giảm giá được tính dựa trên <strong>số phần trăm giảm giá * tổng giá trị</strong> của đơn hàng</li>
                                    </ul>
                        <?php endif ?>
            </div>
            <!-- end coupon -->
            <!-- customer info -->
            <div class="panel panel-info col col-lg-7 col-lg-offset-1">
                        <h4 class="panel-heading"><span class="glyphicon glyphicon-user"></span>Thanh toán đơn hàng</h4>
                        <?php if (true): ?>
                                    <?php echo $this->Form->create('Order', ['url' => ['action' => 'checkout'], 'class' => 'form-horizontal', 'inputDefaults' => ['label' => false]]); ?>
                                    <div class="row">
                                                <?php echo $this->Form->label('name', 'Tên', ['class' => 'col col-lg-3 control-label']); ?>
                                                <div class="col col-lg-9">
                                                            <?php echo $this->Form->input('name', ['placeholder' => 'Nhập tên', 'value' =>'Lê Văn Tèo']); ?>
                                                </div>
                                    </div>
                                    <div class="row">
                                                <?php echo $this->Form->label('email', 'Email', ['class' => 'col col-lg-3 control-label']); ?>
                                                <div class="col col-lg-9">
                                                            <?php echo $this->Form->input('email', ['placeholder' => 'Nhập email', 'value' => 'levanteo@gmail.com']); ?>
                                                </div>
                                    </div>
                                    <div class="row">
                                                <?php echo $this->Form->label('address', 'Địa chỉ', ['class' => 'col col-lg-3 control-label']); ?>
                                                <div class="col col-lg-9">
                                                            <?php echo $this->Form->input('address', ['placeholder' => 'Nhập địa chỉ', 'value' => '123 đường abc, thành phố xyz']); ?>
                                                </div>
                                    </div>
                                    <div class="row">
                                                <?php echo $this->Form->label('phone', 'Điện thoại', ['class' => 'col col-lg-3 control-label']); ?>
                                                <div class="col col-lg-9">
                                                            <?php echo $this->Form->input('phone', ['placeholder' => 'Nhập số điện thoại', 'value' => '123456789']); ?>
                                                </div>
                                    </div>
                                    <div class="row">
                                                <div class="col col-lg-10 col-offset-2">
                                                            <?php echo $this->Form->button('Thực hiện thanh toán', ['type' => 'submit', 'class' => 'btn btn-primary pull-right']) ?>
                                                </div>
                                    </div>
                        <?php echo $this->Form->end(); ?>
                        <?php else: ?>
                                    Bạn phải đăng nhập trước khi thanh toán.
                        <?php endif ?>
            </div>
            <!-- end customer info -->

Để chuyển dữ liệu từ dạng mảng sang dạng đối tượng JSON (dạng text), sử dụng hàm json_encode, ví dụ:

$data = [
                                                'user_id' => 1,
                                                'orders_info' => json_encode($this->Session->read('cart')),
                                                'customer_info' => json_encode($this->request->data['Order']),
                                                'payment_info' => json_encode($this->Session->read('payment')),
                                                'status' => 0
                                    ];

[action checkout() trong OrdersController.php]

/**
 * thanh toán đơn hàng và lưu thông tin mua hàng
 *
 */
            public function checkout() {
                        if ($this->request->is('post')) {
                                    $data = [
                                                'user_id' => 1,
                                                'order_info' => json_encode($this->Session->read('cart')),
                                                'customer_info' => json_encode($this->request->data['Order']),
                                                'payment_info' => json_encode($this->Session->read('payment')),
                                                'status' => 0
                                    ];
                                    if ($this->Order->saveAll($data)) {
                                                $this->Session->delete('cart');
                                                $this->Session->delete('payment');
                                    } else {
                                                $this->Flash->error('Thanh toán không thực hiện được!', ['key' => 'order', 'params' => ['class' => 'alert alert-danger']]);
                                    }
                                    $this->redirect($this->referer());
                        }

            }
-----------
Cập nhật 19/6/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web

Ngu ngơ học làm web (x28) - CakePHP2 - findBy(), date(), between

Tiếp theo của: Ngu ngơ học làm web (x27) - CakePHP2 – Cập nhật giỏ hàng (tt)
-----

Phần x28. CakePHP2 – findBy(), date(), between


Xem (clip số 30a – chickenrainshop):

- request->data() để lấy giá trị từ form post lên server (5":55)

- Sử dụng findBy(7":28)

- Lấy ngày hiện tại date()(9":43)

- Kiểm tra một ngày có nằm trong “ngày bắt đầu” và “ngày kết thúc” (9":59)

- Lưu session theo khóa (13":23)

- redirect về trang hiện tại (15":42)

Đoạn mã cho phần nhập mã giảm giá:

[View\Books\view_cart.ctp]

                        <?php echo $this->Form->postLink('Làm rỗng giỏ hàng', '/books/emptyCart', ['class' => 'col-lg-3 btn btn-default empty']); ?>
                        </div>
            </div>
            <!-- coupon -->
            <div class="panel panel-success col col-lg-4 coupon">
                        <h4 class="panel-heading"><span class="glyphicon glyphicon-barcode"></span> Mã giảm giá</h4>
                        <?php echo $this->Form->create('Coupon', ['url' => ['action' => 'add']], ['class' => 'form-inline']) ?>
                                    <?php echo $this->Form->input('code', ['class' => 'col-lg-9', 'placeholder' => 'Nhập mã giảm giá (coupon)', 'label' => false, 'div' => false]); ?>
                                    <?php echo $this->Form->button('Nhập', ['type' => 'submit', 'class' => 'col-lg-2 btn btn-primary']) ?>
                        <?php echo $this->Form->end(); ?>

                        <h4>Ghi chú:</h4>
                        <ul>
                                    <li>Mỗi mã giảm giá có mức giảm giá khác nhau và chỉ dùng trong khoảng thời gian quy định.</li>
                                    <li>Chỉ dùng một mã giảm giá khi thanh toán đơn hàng.</li>
                                    <li>Số tiền giảm giá được tính dựa trên <strong>số phần trăm giảm giá * tổng giá trị</strong> của đơn hàng</li>
                        </ul>
            </div>
            <!-- end coupon -->
<?php else: ?>
            <div class="panel">
                        Giỏ hàng đang rỗng.
                        Quay về <?php echo $this->Html->link('trang chủ', '/'); ?> để thêm quyển sách vào giỏ hàng.

Thêm mã css vào tập tin chickenrainshop.css:

.coupon {
    padding: 0px;
}

.coupon input {
    padding-left: 4px;
    border-radius: 4px;
    margin-left: 1px;
    padding-right: 1px;
    margin-top: 10px;
    margin-bottom: 10px;
}

.coupon button {
    width: 50px;
    margin-left: 6px;
    text-align: center;
    padding: 0;
    margin-top: 8px;
    margin-bottom: 10px;
    height: 30px;
}

Viết mã cho action add() trong CouponsController.php:

Để kiểm tra một giá trị có trong cơ sở dữ liệu hay không, sử dụng hàm findBy().


findBy<fieldName>(string $value);

Giá trị trả về của findBy() giống với find(‘first’).

Ví dụ, tìm hàng dữ liệu đầu tiên trong bảng coupons, có giá trị trường code = $code:

$coupon = $this->Coupon->findByCode($code);

Để lấy ngày hiện tại sử dụng hàm date(), với định dạng thời gian là: yyyy-mm-dd 00:00:00, ví dụ:
$today = date('Y-m-d H:i:s');

Kết quả sẽ xuất ra là: 2017-06-01 10:14:59

Hàm so sánh một mốc thời gian có nằm trong một khoảng thời gian cho trước hay không? Viết trong ToolComponent.php.

public function between($date, $start, $end, $timezone = 'Asia/Ho_Chi_Minh') {
                                    // thiết lập múi giờ cho server
                                    date_default_timezone_set($timezone);
                                    // chuyển chuỗi thời gian sang dạng Unix timestamp
                                    $date = strtotime($date);
                                    $start = strtotime($start);
                                    $end = strtotime($end);
                                    if ($date >= $start && $date <= $end) {
                                                return true;
                                    } else {
                                                return false;
                                    }

                        }

Mã cho action add() trong CouponsController.php:

public function add() {
                        if ($this->request->is('post')) {
                                    $code = $this->request->data['Coupon']['code'];
                                    $coupon = $this->Coupon->findByCode($code);
                                    if (!empty($coupon)) {
                                                $today = date('Y-m-d H:i:s');
                                                if ($this->Tool->between($today, $coupon['Coupon']['time_start'], $coupon['Coupon']['time_end'])) {
                                                            $this->Session->write('payment.coupon', $coupon['Coupon']['code']);
                                                            $this->Session->write('payment.discount', $coupon['Coupon']['percent']);
                                                            $total = $this->Session->read('payment.total');
                                                            $pay = $total - $total * $coupon['Coupon']['percent']/100;
                                                            $this->Session->write('payment.pay', $pay);
                                                } else {
                                                            $this->Flash->error('Mã giảm giá đã hết hạn!', ['key' => 'coupon', 'params' => ['class' => 'alert alert-danger']]);
                                                }
                                    } else {
                                                $this->Flash->error('Sai mã giảm giá!', ['key' => 'coupon', 'params' => ['class' => 'alert alert-danger']]);
                                    }
                                    $this->redirect($this->referer());
                        }
            }

Đoạn mã cho phần "nhập mã giảm giá", sửa lại như sau:

[View\Books\view_cart.ctp]

<!-- coupon -->
            <div class="panel panel-success col col-lg-4 coupon">
                        <h4 class="panel-heading"><span class="glyphicon glyphicon-barcode"></span> Mã giảm giá</h4>
                        <?php echo $this->Flash->render('coupon'); ?>
                        <!-- kiểm tra chỉ cho hiển thị form nhập coupon nến người dùng chưa nhập lần nào -->
                        <?php if ($this->Session->check('payment.coupon')): ?>
                                    Bạn đã nhập mã giảm giá!
                        <?php else: ?>
                                    <?php echo $this->Form->create('Coupon', ['url' => ['action' => 'add']], ['class' => 'form-inline']) ?>
                                    <?php echo $this->Form->input('code', ['class' => 'col-lg-9', 'placeholder' => 'Nhập mã giảm giá (coupon)', 'label' => false, 'div' => false]); ?>
                                    <?php echo $this->Form->button('Nhập', ['type' => 'submit', 'class' => 'col-lg-2 btn btn-primary']) ?>
                                    <?php echo $this->Form->end(); ?>
                                    <h4>Ghi chú:</h4>
                                    <ul>
                                                <li>Mỗi mã giảm giá có mức giảm giá khác nhau và chỉ dùng trong khoảng thời gian quy định.</li>
                                                <li>Chỉ dùng một mã giảm giá khi thanh toán đơn hàng.</li>
                                                <li>Số tiền giảm giá được tính dựa trên <strong>số phần trăm giảm giá * tổng giá trị</strong> của đơn hàng</li>
                                    </ul>
                        <?php endif ?>
            </div>
            <!-- end coupon -->

Phần mã về “giá tiền được giảm”, “tổng tiền” trong view_cart.ctp được sửa lại như sau:

<?php if ($this->Session->check('payment.coupon')): ?>
<td colspan="2"><strong>Đã giảm                                                                         <small>(Coupon: <?php echo $payment['coupon']; ?> - giảm <?php echo $payment['discount']; ?>%) </small>
            </strong></td>
<td colspan="2"><strong><?php echo $this->Number->currency($payment['total'] - $payment['pay'],' VND',['places' => 0,'wholePosition' => 'after']); ?></strong></td>
<?php else: ?>
            <td colspan="2"><strong>Đã giảm </strong></td>
            <td colspan="2"><strong>0 VND</strong></td>
<?php endif ?>
</tr>
<tr class="success">
            <td></td>
<?php if ($this->Session->check('payment.coupon')): ?>
            <td colspan="2"><h4><strong>Giá phải trả</strong></h4></td>
                                                                                                <td colspan="2"><h4><span class="label label-danger"><?php echo $this->Number->currency($payment['pay'],' VND',['places' => 0,'wholePosition' => 'after']); ?></span></h4></td>
<?php else: ?>
            <td colspan="2"><h4><strong>Giá phải trả</strong></h4></td>
            <td colspan="2"><h4><span class="label label-danger"><?php echo $this->Number->currency($payment['total'],' VND',['places' => 0,'wholePosition' => 'after']); ?></span></h4></td>
<?php endif ?>

</tr>
-----------
Cập nhật 4/6/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web

Ngu ngơ học làm web (x27) - CakePHP2 - Cập nhật giỏ hàng (tt)

Tiếp theo của: Ngu ngơ học làm web (x26) - CakePHP2 – Xem, cập nhật giỏ hàng
-----

Phần x27. CakePHP2 – Cập nhật giỏ hàng (tt)


Xem (clip số 28 – chickenrainshop):
- escapse => false: để hiển thị nội dung html(7":07)

Viết đoạn mã cho nút “Làm rỗng giỏ hàng”, sử dụng một postLink ,
trong [View\Books\view_cart.ctp]:

<?php echo $this->Form->postLink('Làm rỗng giỏ hàng', '/books/emptyCart', ['class' => 'col-lg-3 btn btn-default empty']); ?>

Viết action emptyCart trong BooksController.php

public function emptyCart() {
                        if ($this->request->is('post')) {
                                    $this->Session->delete('cart');
                                    $this->Session->delete('payment');
                                    $this->redirect($this->referer());
                        }
            }

Viết chức năng xóa từng quyển sách.

Viết đoạn mã cho nút X, sử dụng một postLink,
trong [View\Books\view_cart.ctp]:

<?php echo $this->Form->postLink('<span class="glyphicon glyphicon-remove"></span>', '/books/remove/'.$book['id'], ['escape' => false]); ?>

Viết action remove trong BooksController.php

            public function remove($id = null) {
                        if ($this->request->is('post')) {
                                    $this->Session->delete('cart.'.$id);
                                    $cart = $this->Session->read('cart');
                                    if (empty($cart)) {
                                                $this->emptyCart();
                                    } else {
                                                $total = $this->Tool->arraySum($cart, 'quantity', 'sale_price');
                                                $this->Session->write('payment.total', $total);
                                    }
                                    $this->redirect($this->referer());
                        }
            }

Xem (clip số 29bt – chickenrainshop):

Viết chức năng cập nhật số lượng sách.

Nội dung của form cập nhật số lượng, trong [View\Books\view_cart.ctp]:

<?php echo $this->Form->create('Book', ['url' => ['action' => 'quantityUpdate']], ['class' => 'form-inline']) ?>
            <?php echo $this->Form->input('bookId', ['type' => 'hidden', 'value' => $book['id']]); ?>
            <?php echo $this->Form->input('quantity', ['value' => $book['quantity'], 'class' => 'col col-lg-2', 'label' => false, 'div' => false]); ?>
            <?php echo $this->Form->button('Cập nhật', ['class' => 'btn btn-link', 'type' => 'submit']); ?>
            <?php echo $this->Form->end(); ?>

Viết action quantityUpdate() trong controller BooksController.php:

Ý tưởng là:

- Khi gửi form lên thì gửi thêm trường bookId để biết được người dùng đã tăng số lượng của cuốn 
sách nào

- Dựa vào bookId, đọc cuốn sách tương ứng trong Session

- So sánh trường quantity do người dùng gửi lên ($newQuantity) và trường quantity đọc từ Session ($oldQuantity)

- Nếu giá trị người dùng gửi lên lớn hơn 0 và khác giá trị trước đó thì cập nhật lại trường quantity vào Session, đồng thời tính lại giá trị của trường Tổng tiền

- Tải lại trang hiện tại để cập nhật các giá trị mới

public function quantityUpdate() {
                        if ($this->request->is('post')) {
                                    $id = $this->request->data['Book']['bookId'];
                                    $book = $this->Session->read('cart.'.$id);
                                    $oldQuantity = $book['quantity'];
                                    $newQuantity = $this->request->data['Book']['quantity'];
                                    if ($newQuantity > 0 && $newQuantity != $oldQuantity) {
                                                $book['quantity'] = $newQuantity;
                                                $this->Session->write('cart.'.$id, $book);
                                                $cart = $this->Session->read('cart');
                                                $total = $this->Tool->arraySum($cart, 'quantity', 'sale_price');
                                                $this->Session->write('payment.total', $total);
                                    }
                        }
                        $this->redirect($this->referer());

            }
-----------
Cập nhật 1/6/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web

Ngu ngơ học làm web (x26) - CakePHP2 - Xem, cập nhật giỏ hàng

Tiếp theo của: Ngu ngơ học làm web (x25) - CakePHP2 – Tính tiền giỏ hàng, component
-----

Phần x26. CakePHP2 – Xem, cập nhật giỏ hàng


Xem (clip số 27b – chickenrainshop):

- set->(compact()) - gửi nhiều biến lên view (2":56)

- sử dụng layout khác thay thế cho layout default (10":10) 

Đoạn mã cho nút “Xem/Cập nhật giỏ hàng”:

Element [cart.ctp]

<p class="pricetotal"><span class="label">Tổng: <?php echo $this->Number->currency($total,
                                                ' VND', ['places' => 0, 'wholePosition' => 'after']); ?></span></p>
<?php echo $this->Html->link('Xem/Cập nhật giỏ hàng', '/gio-hang', ['class' => 'update-cart btn btn-primary btn-block']); ?>
<?php else: ?>

Vì giao diện bị bể, nên sẽ css một chút.

[chickenrainshop.css]

.update-cart {
    width: 200px;
    text-align: center;
    margin: 0 auto;
    margin-top: 40px;
}

Cấu hình route cho link $this->Html->link('Xem/Cập nhật giỏ hàng', '/gio-hang'):

[routes.php]

Router::connect('/sach-moi', ['controller' => 'books', 'action' => 'latest_books']);
Router::connect('/gio-hang', ['controller' => 'books', 'action' => 'viewCart']);
Router::connect('/tac-gia', ['controller' => 'writers', 'action' => 'index']);

Viết action viewCart trong [BooksController.php]

/*
* xem chi tiết giỏ hàng
*/
            public function viewCart() {
                        $cart = $this->Session->read('cart');
                        $payment = $this->Session->read('payment');
                        $this->set(compact('cart', 'payment'));
                        $this->set('title_for_layout', 'Giỏ hàng');
            }
           
            public function addToCart($id = null) {

Để gửi nhiều hơn một biến lên view, sử dụng hàm compact, ví dụ:

$this->set(compact('cart', 'payment'));

Viết view view_cart: do view view_cart sử dụng layout khác so với layout default, vì vậy cần phải tạo layout trước (layout cart.ctp).

Tạo layout mới, có tên là cart.ctp.

[Layouts\cart.ctp]

<!DOCTYPE html>
<html>
<head>
            <?php echo $this->Html->charset(); ?>
            <title>
                        <?php echo $title_for_layout; ?>
            </title>
            <?php
                        echo $this->Html->meta('icon');
                        echo $this->Html->css('bootstrap.min');
                        echo $this->Html->css('chickenrainshop');
                        echo $this->fetch('meta');
                        echo $this->fetch('css');
                        echo $this->fetch('script');
            ?>
</head>
<body>
            <div id="container" class="container">
                        <div id="header">
                                    <nav class="navbar navbar-default">
                                                <div class="navbar-header">
                                                            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#mainmenu">
                                                <span class="sr-only">Toggle navigation</span>
                                                <span class="icon-bar"></span>
                                                <span class="icon-bar"></span>
                                                <span class="icon-bar"></span>
                                    </button>
                                    <a href="#" class="navbar-brand">Chickenrainshop</a>
                        </div>
                        <div class="navbar-collapse collapse" id="mainmenu">
                                    <ul class="nav navbar-nav">
                                    <li class="active"><?php echo $this->Html->link('Sách mới', '/sach-moi') ?></li>
                                    <li><a href="#ban-chay">Sách bán chạy</a></li>
                                    <li><a href="#lien-he">Liên hệ</a></li>
                                    </ul>
                                    <ul class="nav navbar-nav pull-right">
                                                <?php
                                                            echo $this->Form->create('Book', [
                                                                        'url' => ['action' => 'get_keyword'],
                                                                        'class' => 'navbar-form search'
                                                                        ]);
                                                            echo $this->Form->input('keyword',[
                                                                        'label' => '',
                                                                        'style' => 'width: 200px',
                                                                        'placeholder' => 'Tìm kiếm...'
                                                                        ]);
                                                            echo $this->Form->end();
                                                ?>

                                    </ul>
                        </div>
                                    </nav>
                        </div><!-- #header -->
                        <div id="content">
                                    <div class="row">
                                                <div class="content col col-lg-12">
                                                            <?php echo $this->fetch('content'); ?>
                                                </div><!-- content -->
                                    </div>
                        </div>
                        <div id="footer">
                                    <div class="container">
                                                <p class="text-muted pull-right">Học CakePHP2</p>
                                    </div>
                        </div>
            </div>
            <?php echo $this->Html->script('jquery'); ?>
            <?php echo $this->Html->script('bootstrap.min'); ?>
</body>
</html>

Để sử dụng layout cart vừa tạo ở trên, trong [BooksController.php action viewCart()] thêm dòng lệnh $this->layout= ‘cart’;

Ví dụ:

public function viewCart() {
                        $this->layout = 'cart';
                        $cart = $this->Session->read('cart');

[View\Books\view_cart.ctp]

<?php if ($this->Session->check('cart')): ?>
            <div class="panel">
                        <h4 class="panel-heading"><span class="glyphicon glyphicon-shopping-cart"></span>Giỏ hàng của bạn</h4>
                        <div class="row">
                                    <div class="chi-tiet-gio-hang">
                                                <table class="table table-striped">
                                                            <thead>
                                                                        <tr>
                                                                                    <th>STT</th>
                                                                                    <th>Tên sách</th>
                                                                                    <th>Số lượng</th>
                                                                                    <th>Giá</th>
                                                                                    <th>Xóa</th>
                                                                        </tr>
                                                            </thead>
                                                            <tbody>
                                                                        <?php $i = 1; ?>
                                                                        <?php foreach ($cart as $book): ?>
                                                                                    <tr>
                                                                                                <td><?php echo $i++; ?></td>
                                                                                                <td><?php echo $this->Html->link($book['title'], '/'.$book['slug']); ?></td>
                                                                                                <td class='row'>
                                                                                                <?php echo $this->Form->create('Book', ['class' => 'form-inline']) ?>
                                                                                                            <?php echo $this->Form->input('quantity', ['value' => $book['quantity'], 'class' => 'col col-lg-2', 'label' => false, 'div' => false]); ?>
                                                                                                            <?php echo $this->Form->button('Cập nhật', ['class' => 'btn btn-link', 'type' => 'submit']); ?>
                                                                                                <?php echo $this->Form->end(); ?>
                                                                                                </td>
                                                                                                <td><?php echo $this->Number->currency($book['sale_price'],' VND',['places' => 0,'wholePosition' => 'after']); ?>
                                                                                                </td>
                                                                                                <td><a href="#"><span class="glyphicon glyphicon-remove"></span></a></td>
                                                                                    </tr>
                                                                        <?php endforeach ?>
                                                                        <tr>
                                                                                    <td></td>
                                                                                    <td colspan="2"><strong>Tổng cộng</strong></td>
                                                                                    <td colspan="2"><strong><?php echo $this->Number->currency($payment['total'],' VND',['places' => 0,'wholePosition' => 'after']); ?></strong></td>
                                                                        </tr>
                                                                        <tr>
                                                                                    <td></td>
                                                                                    <td colspan="2"><strong>Đã giảm <small>(Coupon: CAKEPHP - giảm 10%)</small></strong></td>
                                                                                    <td colspan="2"><strong>0 VND</strong></td>
                                                                        </tr>
                                                                        <tr class="success">
                                                                                    <td></td>
                                                                                    <td colspan="2"><h4><strong>Giá phải trả</strong></h4></td>
                                                                                    <td colspan="2"><h4><span class="label label-danger"><?php echo $this->Number->currency($payment['total'],' VND',['places' => 0,'wholePosition' => 'after']); ?></span></h4></td>
                                                                        </tr>
                                                            </tbody>
                                                </table>
                                    </div>
                                    <button type="submit" class="col-lg-3 btn btn-default empty">Làm rỗng giỏ hàng</button>
                        </div>
            </div>

<?php else: ?>
            <div class="panel">
                        Giỏ hàng đang rỗng.
                        Quay về <?php echo $this->Html->link('trang chủ', '/'); ?> để thêm quyển sách vào giỏ hàng.
            </div>
<?php endif ?>

Thêm đoạn mã sau vào chickenrainshop.css:

.chi-tiet-gio-hang {
    width: 800px;
    margin: 0 auto;
}

.empty {
    margin-left: 30px;
    background: #C0C0C0;
    color: #FFF;

}
-----------
Cập nhật 31/5/2017
-----------
Xem thêm:
- Tổng hợp các bài viết về Ngu ngơ học làm web