-----
Phần x17. CakePHP2
– Search trên hai table, paginate, validate
Xem (clip số 22b – chickenrainshop):
Phần này sẽ thực hiện tìm kiếm mở rộng, nghĩa là cho phép
người dùng nhập vào một từ khóa, từ khóa này có thể là (một phần) tên một cuốn
sách hoặc (một phần) tên của tác giả, và kết quả trả về là cuốn sách có tên
hoặc tác giả liên quan.
Câu lệnh truy vấn được thực hiện trên model Book, tuy nhiên
cần phải truy vấn đến tên tác giả, nên phải kết nối tới model Writer, việc kết
nối giữa Book và Writer được thực hiện thông qua bảng trung gian books_writers,
sử dụng từ khóa joins.
Đọc thêm về alisa tại đây: http://www.chiasephp.net/c65d65-bai-13-su-dung-as-alias-trong-mysql.html
[hàm search() trong BooksController.php] thay đổi như sau:
public function search() {
$notFound
= false;
if
($this->request->is('post')) {
$keyword
= $this->request->data['Book']['keyword'];
$books
= $this->Book->find('all',
[
'fields'
=> ['title', 'image', 'sale_price', 'slug'],
//
'contain' => ['Writer.name', 'Writer.slug'],
'contain'
=> ['Writer' => ['name', 'slug']],
'order'
=> ['Book.created' => 'desc'],
'conditions'
=> [
'published'
=> 1,
'or' => [
'title
like' => '%'.$keyword.'%',
'w.name
like' => '%'.$keyword.'%'
]
],
'joins'
=> [
[
'table'
=> 'books_writers',
'alias'
=> 'bw',
'conditions'
=> 'bw.book_id = Book.id'
],
[
'table'
=> 'writers',
'alias'
=> 'w',
'conditions'
=> 'bw.writer_id = w.id'
]
]
]);
if
(!empty($books)) {
$this->set('results',
$books);
}
else {
$notFound
= true;
}
}
$this->set('notFound',
$notFound);
}
Phân trang dữ liệu tìm kiếm được.
[hàm search() trong BooksController.php] thay đổi như sau:
public function search() {
$notFound
= false;
if
($this->request->is('post')) {
$keyword
= $this->request->data['Book']['keyword'];
$this->paginate = [
'fields'
=> ['title', 'image', 'sale_price', 'slug'],
//
'contain' => ['Writer.name', 'Writer.slug'],
'contain'
=> ['Writer' => ['name', 'slug']],
'order'
=> ['Book.created' => 'desc'],
'conditions'
=> [
'published'
=> 1,
'or'
=> [
'title
like' => '%'.$keyword.'%',
'w.name
like' => '%'.$keyword.'%'
]
],
'joins'
=> [
[
'table'
=> 'books_writers',
'alias'
=> 'bw',
'conditions'
=> 'bw.book_id = Book.id'
],
[
'table'
=> 'writers',
'alias'
=> 'w',
'conditions'
=> 'bw.writer_id = w.id'
]
]
];
$books = $this->paginate('Book');
if
(!empty($books)) {
$this->set('results',
$books);
}
else {
$notFound
= true;
}
}
$this->set('notFound',
$notFound);
}
Trong search.ctp thêm dòng mã sau:
<?php if(isset($results) && $notFound == false): ?>
<?php
echo $this->element('book', ['books' => $results]); ?>
<?php echo
$this->element('pagination', ['object' => 'quyển sách']); ?>
Thiết lập kiểm tra dữ liệu cho trường ‘keyword’:
[Model\Book.php]
public $validate = array(
'keyword' => array(
'rule' => 'notBlank',
'message' => 'Bạn phải nhập từ
khóa để tìm kiếm!'
),
'title'
=> array(
'notBlank'
=> array(
[View\Books\search.ctp]
<?php echo $this->Form->create('Book', ['novalidate'
=> true]) ?>
<?php echo
$this->Form->input('keyword',
[
'label'
=> '',
'placeholder'
=> 'Nhập từ khóa tìm kiếm...',
'error'
=> false,
'required'
=> false
]);
?>
<?php if
(isset($errors)): ?>
<?php
foreach ($errors as $error): ?>
<?php
echo $error[0]; ?>
<?php
endforeach ?>
<?php endif
?>
<?php if
(isset($results) && $notFound == false): ?>
<?php
echo $this->element('book', ['books' => $results]); ?>
<?php
echo $this->element('pagination', ['object' => 'quyển sách']); ?>
<?php
elseif($notFound == true): ?>
Không
tìm thấy quyển sách này!
<?php endif
?>
<?php echo $this->Form->end('Search'); ?>
[Controller\BooksController.php search()]
public function search() {
$notFound
= false;
if
($this->request->is('post')) {
$this->Book->set($this->request->data);
if
($this->Book->validates()) {
$keyword
= $this->request->data['Book']['keyword'];
$this->paginate
= [
'fields'
=> ['title', 'image', 'sale_price', 'slug'],
//
'contain' => ['Writer.name', 'Writer.slug'],
'contain'
=> ['Writer' => ['name', 'slug']],
'order'
=> ['Book.created' => 'desc'],
'conditions'
=> [
'published'
=> 1,
'or'
=> [
'title
like' => '%'.$keyword.'%',
'w.name
like' => '%'.$keyword.'%'
]
],
'joins'
=> [
[
'table'
=> 'books_writers',
'alias'
=> 'bw',
'conditions'
=> 'bw.book_id = Book.id'
],
[
'table'
=> 'writers',
'alias'
=> 'w',
'conditions'
=> 'bw.writer_id = w.id'
]
]
];
$books
= $this->paginate('Book');
if
(!empty($books)) {
$this->set('results',
$books);
}
else {
$notFound
= true;
}
} else {
$errors =
$this->Book->validationErrors;
$this->set('errors',
$errors);
}
}
$this->set('notFound',
$notFound);
}
Để không hiển thị thông báo lỗi validate mặc định ngay dưới
một input, thêm thuộc tính 'error' => false, ví dụ:
<?php echo $this->Form->input('keyword',
[
'label'
=> '',
'placeholder'
=> 'Nhập từ khóa tìm kiếm...',
'error' => false
]);
?>
-----------
Cập nhật 15/5/2017
-----------