Phần 3 sẽ là phần hiển thị danh sách user trong cơ sở dữ liệu, edit, changepass, xoá user.

1 Log out sau khi đăng nhập:

Ở phần 2 chúng ta đã login thành công user vào trang quản trị, và đã chạy logout bằng một link trực tiếp, bây giờ mình sẽ gọi link này thông qua view để thực hiện thao tác logout trực quan hơn.

Sau khi đăng nhập thành công các bạn có thể thấy phía trên bên phải có icon giống như hình sau:

Icon user profile

 

Chúng ta tiến hành tìm html của Logout trong hình, nó nằm ở file /app/View/Elements/admin/navigate.ctp có nội dung như sau:


<li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>

Thay thế bằng:


<li>
<?php echo $this->Html->link('<i class="fa fa-sign-out fa-fw"></i>Logout',array('controller'=>'users','action'=>'logout'),array('escape'=>false))?>
</li>

Cách viết trên là cách viết HtmlHelper của Cakephp Framework nó cũng sẽ tạo ra thẻ <a> với href là /admin/users/logout

Đương nhiên cách đơn giản hơn là thế này:


<li>
<a href="/admin/users/logout"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>

Các bạn tiến hành test bằng cách đăng nhập và đăng xuất ra, khi đăng xuất sẽ được chuyển hướng đến trang login(đã được cấu hình ở loginRedirect, logoutRedirect trong AppController.php), việc chuyển hướng khi đăng nhập chúng ta có thể can thiệp vào ở action login của UsersController.php, ví dụ như đăng nhập xong chúng ta kiểm tra quyền của user sau đó chuyển hướng đến trang cần đến, đoạn code sau là ví dụ sau khi đăng nhập kiểm tra role_id là 2 sẽ chuyển đến/admin/candidates/index ngược lại chuyển đến/admin/categories/index, không cần thêm vào:


if($this->Auth->login()){
if($this->Auth->user('role_id')==2){
$this->redirect('/admin/candidates/index');
}else{
$this->redirect('/admin/categories/index');
}
}else{
$this->Session->setFlash('Username hoặc pass sai');
}

OK vậy là xong phần logout.

2 Danh sách users cakephp:

Url chạy: http://doctruyen.local/admin/users/list

Phần này là để liệt kê danh sách các user trong table users

a. Đầu tiên là tạo action admin_list trong UsersController.php nội dung:


public function admin_list(){
//Lay du lieu trong table users
$array_user = $this->User->find('all', array(
'conditions'=>array('id > 0'),
'recursive' =>-1
));
//đưa dữ liệu lấy được qua view bằng biến users
$this->set('users', $array_user);
}

Cách lấy dữ liệu như thế nào thì các bạn xem lại bài [Cakephp] Bài 5 – Truy vấn CSDL

b . Tiếp theo là view list danh sách user admin_list.ctp: Các bạn cứ copy file /app/View/Dashboards/admin_index.ctp thành /app/View/Users/admin_list.ctp. Chạy url danh sách này sẽ có giao diện như ở dashboards là OK.

c. Mở file /app/webroot/template_admin/pages/tables.html chúng ta sẽ lấy html của file này copy vào admin_list.ctp ở trên. Tìm trong file tables.html  thẻ div có id là page-wrapper nếu các bạn làm giống mình thì nó sẽ từ dòng 376- 1110 copy đoạn đó và thay thế vào đoạn 4- 544 trong admin_list.ctp (tương ứng thẻ div có id là page-wrapper) chạy lại url nó sẽ có giao diện giống như chạy file tables.html, nếu chỉ nhìn sơ qua các bạn không biết nó khác chổ nào đâu, nhưng chúng ta phải tận dụng cái có sẳn của SB Admin 2 này, mình sẽ sử dụng thêm cái hay của nó là tìm kiếm dữ liệu, phân trang… của datatables

Muốn phân biệt kỉ hơn các bạn nhìn ở tables.html khi hiển thị có khung search nhưng của admin_list.ctp thì không có, vì chúng ta mới dùng html để hiển thị thui cần phải có js, css nữa, tiến hành sử dụng HtmlHelper để đưa js và css vào view admin_list.ctp, các bạn có thể để ở file dùng chung là head.ctp trong Elements sử dụng được ở tất cả các view hoặc view nào cần thì sử dụng thui, ở đây mình chọn cách 2, để nó nhẹ load trang vì không phải lúc nào cũng hiện danh sách. Mình thêm đoạn sau vào đầu file admin_list.ctp:

<?php
echo $this->Html->css(array(
'../template_admin/vendor/datatables-plugins/dataTables.bootstrap.css',
'../template_admin/vendor/datatables-responsive/dataTables.responsive.css',
));
echo $this->Html->script(array(
'../template_admin/vendor/datatables/js/jquery.dataTables.min.js',
'../template_admin/vendor/datatables-plugins/dataTables.bootstrap.min.js',
'../template_admin/vendor/datatables-responsive/dataTables.responsive.js',
));
?>
<script>
$(document).ready(function() {
$('#dataTables-example').DataTable({
responsive: true
});
});
</script>

Chay lại url bạn sẽ thấy sự khác biệt xuất hiện thêm khung search, chạy phân trang, bạn test luôn phần search có hiệu quả k?…

d. Lấy dữ liệu trong UsersController.php đưa ra.

Phần a ở trên chúng ta đã lấy dữ liệu đưa ra biến users ở view, nó là 1 mảng các users nên ở view chúng ta chỉ việc foreach cái mảng này mà thui. Xem giao diện admin_list hiện tại là các html mặc định chúng ta không cần sử dụng hết, nếu tìm kiếm các bạn có thể thấy có 5 class=”row”, chúng ta sẽ giữ lại 2 class=”row” phía trên còn 3 class dưới xoá bỏ đi. Trong class row thứ 2 có thẻ div với class là class=”well” cũng xoá bỏ luôn.

Lúc này chỉ còn lại 1 table hiển thị mà thôi, trong table này có <tbody> nội dung bên trong chính là dữ liệu hiển thị, mình tiếp tục xoá tất cả các thẻ <tr> </tr> trong đây, chỉ để lại 1 cái đầu tiên. Rồi tiến hành foreach mảng users đã được đưa ra trong UsersController.php


<?php foreach($users as $key => $val){
?>
<tr>
<td><?php echo $val['User']['id']?></td>
<td><?php echo $val['User']['name']?></td>
<td><?php echo $val['User']['username']?></td>
<td><?php echo $val['User']['email']?></td>
<td>
<?php echo $this->Html->link('Edit',array('controller'=>'users','action'=>'edit',$val['User']['id']), array('class' => 'btn btn-warning'));
?>
<?php echo $this->Html->link('Del',array('controller'=>'users','action'=>'delete',$val['User']['id']), array('class' => 'btn btn-danger'));
?>
</td>
</tr>
<?php }?>

Công dụng của datatables  còn có thể làm nhiều việc như sắp xếp dữ liệu một cách thông minh, các bạn có thể tự tìm hiểu thêm nhá.

Trong này có 2 nút Edit và Del dùng để cập nhật thông tin và xoá 1 user khi thao tác.

e. Xoá user được chọn


public function admin_delete($id = null){
if($this->request->is('get')){
$data = $this->User->find('first', array(
'fields' => array('id','name'),
'conditions'=>array('id'=>$id),
'recursive'=>-1
));
if(!empty($data)){
$this->Session->setFlash('Success');
$this->User->delete($id);
}else{
$this->Session->setFlash('Error');
}
$this->redirect(array('action'=>'list'));
}
}

Nhấp vào nút Del trong danh sách user, với id truyền trên url để xoá user, đoạn code trên sẽ kiểm tra xem id đó có tồn tại user hay không, có sẽ xóa và thông báo Success, ngược lại là Error trên action list, phần thông báo này mình sẽ hướng dẫn layout cho đẹp ở cuối bài nha.

f. Cập nhật user:

Nút Edit nhá, đầu tiên tạo action trong UsersController.php admin_edit và một file view trong app/View/Users/admin_edit.ctp

Trong phần edit này mình chỉ chỉnh sửa 3 phần là username, email, name thui nha, phần khác các bạn tự mở rộng thêm, vẫn tiếp tục sử dụng HtmlHelper trong view nội dung các bạn tham khảo trong file tải về, nội dung chính của admin_edit.ctp là:


<?php echo $this->Form->create(array('id'=>'appForm', 'inputDefaults'=>array('label'=>false, 'div'=>false))); ?>
<div class="form-group">
<label>Username</label>
<?php echo $this->Form->input('username', array('class'=>'form-control')); ?>
</div>

<div class="form-group">
<label>Email</label>
<?php echo $this->Form->input('email', array('class'=>'form-control')); ?>
</div>

<div class="form-group">
<label>Full name</label>
<?php echo $this->Form->input('name', array('class'=>'form-control')); ?>
</div>

<button type="submit" class="btn btn-default">Save</button>
<?php echo $this->Form->end();?>

Trong UsersController.php đâu tiên phải hiển thị thông tin user mà ta edit thông qua biến id, nếu để ý sẽ thấy trên url có id mà user sẽ được chỉnh sửa http://doctruyen.local/admin/users/edit/2, với url này là id =2, đoạn code để hiển thị thông tin như sau:


public function admin_edit($id = null){
$this->User->id = $id;
$this->request->data = $this->User->read();//đọc thông tin user với $id, gán vào request->data hiển thị view
}

Nếu nội dung các bạn là giống mình sẽ được kết quả như sau:

edit user

Đó là phần hiển thị thông tin user, tiếp theo sẽ là phần cập nhật, khi nhấn vào save nó sẽ post dữ liệu trong form qua controller, và chúng ta sẽ lấy dữ liệu post thông qua $this->request->data, nó là một array, các bạn có thể print_r($this->request->data); để xem dữ liệu này.

Để lưu dữ liệu bảng trong CakePHP ta dùng phương thức set và save, cụ thể sẽ như sau:


public function admin_edit($id = null){
if($this->request->is('post') || $this->request->is('put')){
//print_r($this->request->data);exit();
$this->User->id = $id;
$this->User->save($this->request->data);$this->Session->setFlash('Success','default',array('class'=>"alert alert-success"));
}else{
$this->User->id = $id;
$this->request->data = $this->User->read();//đọc thông tin user với $id, gán vào request->data hiển thị view
}
}

Với đoạn trên thì chúng ta có thể cập nhật thông tin user được rồi.

Nếu các bạn muốn lưu một dữ liệu nào đó không được post từ form qua thì ta dùng set để gán dữ liệu vào, ở đây mình cập nhật lại trường date_updated là ngày giờ hiện tại của hệ thống, để đoạn code sau trước khi gọi save: $this->User->set(array(‘date_updated’ => date(‘Y:m:d H:i:s’)));

Đương nhiên phần kiểm tra dữ liệu đúng sai email chẳng hạn… các bạn hãy tự tham khảo thêm đương nhiên nếu các bạn tải source mình về sẽ có các phần này, nhưng mình không nhắc ở đây @@.

Thông thường khi thực hiện một tác vụ nào đó, chúng ta nên thông báo cho người sử dụng biết nó thành công hay thất bại

g. Thông báo:

Thông báo này sử dụng session, tốt nhất là nên khai báo Session trong AppController.php nha.

Nó cũng rất đa dạng, và chúng ta đều có thể tạo ra một thông báo cho riêng mình.

Các bạn có thể thấy các file view(.ctp) của mình để có đoạn <?php echo $this->Session->flash();?> nó chính là chổ để hiển thị thông báo mà chúng ta định nghĩa trong controller, bạn muốn thông ở vị trí nào thì để nó ở vị trí đó, thông thường nên để ở View/Layouts/layout của bạn, ở đây mình cần làm ví dụ nên để trong view của users cho dễ hình dung, lấy ví dụ là phần cập nhật user ở trên, khi cập nhật user thành công ta thông báo success(cái này viết trong UsersController.php)

if($this->User->save($this->request->data)){
$this->Session->setFlash('Success');
}

Với đoạn code trên sau khi nhấn Save sẽ có xuất hiện chữ Success trong file view hiện tại. kiểm tra phần tử html sẽ được như hình sau:

edit user success

Nó có class mặc định là message, bây giờ chúng ta sẽ thêm class khác vào để nó hiển thị đẹp hơn, sửa lại đoạn code phía trên thành $this->Session->setFlash(‘Success’,’default’,array(‘class’=>”alert alert-success”)); đây là cách chúng ta thay thế class của câu thông báo, với default là layout mặc định của thông báo, sẽ có phần mình thay thế layout mặc định này.

Tiếp tục cập nhật lại user và thông báo sẽ thành:

edit user success

Điều hay của thông báo này là khi ta chỉ định nó ở view nào thì nó sẽ hiển thị view đó và nó sẽ được huỷ session ngay thì hiển thị thành công. Các bạn có thể sửa lại sau khi cập nhật thành công ra thông báo success và chuyển hướng đến danh sách user,action edit được sửa lại như sau:


public function admin_edit($id = null){
if($this->request->is('post') || $this->request->is('put')){
//print_r($this->request->data);exit();
$this->User->id = $id;
$this->User->set(array('date_updated' => date('Y:m:d H:i:s')));
if($this->User->save($this->request->data)){
$this->Session->setFlash('Success','default',array('class'=>"alert alert-success"));
$this->redirect(array('action'=>'list'));
}
}else{
$this->User->id = $id;
$this->request->data = $this->User->read();//đọc thông tin user với $id, gán vào request->data hiển thị view
}
}

h. Thay đổi nav admin.

Ở trên chúng ta đã thực hiện logout user bằng cách click vào icon log, còn danh sách hiện tại chỉ có thể chạy bằng link trực tiếp, ở đây sẽ làm một menu để thực hiện thao tác liệt kê danh sách user.

Tìm đến file app/View/Elements/admin/navigate.ctp và search từ khoá Charts, nó sẽ được chứa bởi thẻ <li></li>


<li>
<a href="#"><i class="fa fa-bar-chart-o fa-fw"></i> Charts<span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li>
<a href="flot.html">Flot Charts</a>
</li>
<li>
<a href="morris.html">Morris.js Charts</a>
</li>
</ul>
<!-- /.nav-second-level -->
</li>

thay thế nó bằng


<li>
<a href="#"><i class="fa fa-bar-chart-o fa-fw"></i> Users<span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li>
<a href="/admin/users/list">List</a>
</li>
<li>
<a href="#">Add</a>
</li>
</ul>
<!-- /.nav-second-level -->
</li>

Từ đây khi muốn xem danh sách user thì đã có Menu User bên phải rùi, có thể làm tương tự cho các danh sách khác.

Phần sau sẽ là thêm user mới, một phần của thể loại truyện để hiển thị bên ngoài. Mời các bạn theo dõi sau…

Kết luận

  1. Nếu có thắc mắc gì các bạn để lại comment bên dưới mình sẽ trả lời sớm nhất có thể.
  2. Cảm ơn các bạn đã đọc.

Nongdanit.info
[Cakephp] Bài 24 – Toàn tập website truyện tranh phần 3
Tagged on: