Ngu ngơ học làm web (x11) - CakePHP2 – Phân trang nâng cao

Tiếp theo của: Ngu ngơ học làm web (x10) - CakePHP2 – Bài tập Link “thân thiện”
-----

Phần x11. CakePHP2 – Phân trang nâng cao


Xem (clip số 17a – chickenrainshop):

Hiển thị category và các book thuộc về category, thực hiện phân trang cho book:

Viết lại action view của controller Categories,

[CategoriesController\view.php]

public function view($slug = null) {
                        $options = [
                                    'conditions' => ['Category.slug' => $slug],
                                    'recursive' => -1
                        ];
                        $category = $this->Category->find('first', $options);
                        if (empty($category)) {
                                    throw new NotFoundException(__('Không tìm thấy thể loại sách này'));
                        }
                        $this->set('category', $category);
                        // phân trang cho các book thuộc thể loại ở trên
                        $this->paginate = [
                                    'fields' => ['id', 'title', 'slug', 'image', 'sale_price'],
                                    'order' => ['created' => 'desc'],
                                    'limit' => 5,
                                    'contain' => [
                                                'Writer' => ['name', 'slug'],
                                                'Category' => ['slug']
                                                ],
                                    'conditions' => [
                                                'published' => 1,
                                                'Category.slug' => $slug
                                                ],
                                    'paramType' => 'querystring'
                        ];
                        $books = $this->paginate('Book');
                        $this->set('books', $books);
            }

Ý nghĩa của hàm $this->paginate() ở đoạn mã trên là:

- lấy thông tin của sách, gồm:  ('id', 'title', 'slug', 'image', 'sale_price')

- lấy thêm thông tin về tác giả (writer) của sách: ('contain' => ['Writer' => ['name', 'slug']])

- chỉ lấy các cuốn sách có cùng thể loại: ('Category.slug' => $slug)

- vì vậy cần phải lấy thêm thông tin về thể loại của sách: ('contain' => ['Category' => ['slug']])

[View\Categories\view.php]

<div class="categories view">
<h2><?php echo __('Category'); ?></h2>
            <dl>
                        <dt><?php echo __('Name'); ?></dt>
                        <dd>
                                    <?php echo h($category['Category']['name']); ?>
                                    &nbsp;
                        </dd>
                        <dt><?php echo __('Description'); ?></dt>
                        <dd>
                                    <?php echo h($category['Category']['description']); ?>
                                    &nbsp;
                        </dd>
            </dl>
</div>
<div class="related">
            <h3><?php echo __('Related Books'); ?></h3>
            <?php if (!empty($books)): ?>
                        <?php echo $this->element('book', ['books' => $books]); ?>
                        <?php echo $this->element('pagination', ['object' => 'quyển sách']); ?>
            <?php endif; ?>
</div>

Học thêm cách viết lệnh if:

<?php if( ): ?>
            // đoạn lệnh trong if
<?php endif; ?>

Ở đoạn mã trên thấy có hàm h(), hàm này để làm gì?

Đọc về hàm h() tại đây: https://api.cakephp.org/2.7/function-h.html

Hàm h() là một hàm của CakePHP, nó thực chất là hàm htmlspecialchars của PHP.

Hàm htmlspecialchars để làm gì?

Đọc thêm về hàm htmlspecialchar tại đây: http://php.net/manual/en/function.htmlspecialchars.php

Hàm htmlspecialchars để chuyển các kí tự đặc biệt sang dạng htmlentities, ví dụ:

Kí tự
Được thay bằng (dạng htmlentities)
& (ampersand)
&amp;
“ (double quote)
&quot;
‘ (single quote)
&#039;
< (less than)
&lt;
> (greater than)
&gt;

Chạy thử ví dụ sau, để hiểu thêm về hàm h:

<?php
            $test = "<b>Có in đậm không</b>";
            echo h($test); // trình duyệt sẽ không thực thi thẻ html
            echo $test; // trình duyệt có thực thi thẻ html
?>
Cấu hình route cho link phân trang:

Khi bấm vào các link trong phần phân trang, đường dẫn sẽ có dạng sau:

-> cần phải cấu hình lại trong routes.php

Chuyển dòng này:

Router::connect('/danh-muc/:name', ['controller' => 'categories', 'action' => 'view'], ['pass' => 
['name']]);

Thành,

Router::connect('/danh-muc/*', ['controller' => 'categories', 'action' => 'view']);

Trong đó, dấu ‘*’ đại diện cho chuỗi bất kì.

Xem (clip số 17b – chickenrainshop):

Phân trang dữ liệu với quan hệ nhiều - nhiều.

Ví dụ, hiển thị writer và các book thuộc về writer, thực hiện phân trang cho book:

Lệnh joins (phút 3:10).

Lệnh joins để kết nối bảng: books với books_writers, và books với writers.  

$this->paginate = [
                                    'fields' => ['id', 'title', 'slug', 'image', 'sale_price'],
                                    'order' => ['created' => 'desc'],
                                    'limit' => 2,
                                    'contain' => [
                                                'Writer' => ['name', 'slug']
                                                ],
                                    'joins' => [
                                                [
                                                            'table' => 'books_writers',
                                                            'alias' => 'BookWriter',
                                                            'conditions' => 'BookWriter.book_id = Book.id'
                                                ],
                                                [
                                                            'table' => 'writers',
                                                            'alias' => 'Writer',
                                                            'conditions' => 'BookWriter.writer_id = Writer.id'
                                                ]
                                    ],
                                    'conditions' => [
                                                'published' => 1,
                                                'Writer.slug' => $slug
                                                ],
                                    'paramType' => 'querystring'
                        ];

[action view trong WritersController.php]

            public function view($slug = null) {
                        $options = [
                                    'conditions' => [
                                                'Writer.slug' => $slug
                                                ],
                                    'recursive' => -1
                        ];
                        $writer = $this->Writer->find('first', $options);
                        if(empty($writer)) {
                                    throw new NotFoundException(__('Không tìm thấy tác giả này!'));
                        }
                        $this->set('writer', $writer);
                        // phân trang cho các book thuộc tác giả ở trên
                        $this->paginate = [
                                    'fields' => ['id', 'title', 'slug', 'image', 'sale_price'],
                                    'order' => ['created' => 'desc'],
                                    'limit' => 2,
                                    'contain' => [
                                                'Writer' => ['name', 'slug']
                                                ],
                                    'joins' => [
                                                [
                                                            'table' => 'books_writers',
                                                            'alias' => 'BookWriter',
                                                            'conditions' => 'BookWriter.book_id = Book.id'
                                                ],
                                                [
                                                            'table' => 'writers',
                                                            'alias' => 'Writer',
                                                            'conditions' => 'BookWriter.writer_id = Writer.id'
                                                ]
                                    ],
                                    'conditions' => [
                                                'published' => 1,
                                                'Writer.slug' => $slug
                                                ],
                                    'paramType' => 'querystring'
                        ];
                        $books = $this->paginate('Book');
                        $this->set('books', $books);
            }

[View Writers\ view.ctp]

<div class="writers view">
<h2><?php echo __('Writer'); ?></h2>
            <dl>
                        <dt><?php echo __('Name'); ?></dt>
                        <dd>
                                    <?php echo h($writer['Writer']['name']); ?>
                                    &nbsp;
                        </dd>
                        <dt><?php echo __('Biography'); ?></dt>
                        <dd>
                                    <?php echo h($writer['Writer']['biography']); ?>
                                    &nbsp;
                        </dd>
            </dl>
</div>
<div class="related">
            <h3><?php echo __('Related Books'); ?></h3>
            <?php if (!empty($books)): ?>
                        <?php echo $this->element('book', ['books' => $books]); ?>
                        <?php echo $this->element('pagination', ['object' => 'quyển sách']); ?>
            <?php endif; ?>
</div>

[routes.php]

Sửa dòng mã:

Router::connect('/tac-gia/:name', ['controller' => 'writers', 'action' => 'view'], ['pass' => ['name']]);
Thành:


Router::connect('/tac-gia/*', ['controller' => 'writers', 'action' => 'view']);
-----------
Cập nhật 28/4/2017
-----------
Xem thêm:
Tổng hợp các bài viết về Ngu ngơ học làm web