-----
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']); ?>
</dd>
<dt><?php
echo __('Description'); ?></dt>
<dd>
<?php
echo h($category['Category']['description']); ?>
</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)
|
&
|
“ (double quote)
|
"
|
‘ (single quote)
|
'
|
< (less than)
|
<
|
> (greater than)
|
>
|
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']); ?>
</dd>
<dt><?php
echo __('Biography'); ?></dt>
<dd>
<?php
echo h($writer['Writer']['biography']); ?>
</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
-----------