Ngu ngơ học làm web (x42) - CakePHP2 - admin, route prefix, request->params

Tiếp theo của: Ngu ngơ học làm web (x41) - CakePHP2 – updateAll, CakeEmail, config smtp
-----

Phần x42. CakePHP2 – admin, route prefix, request->params


Xem (clip số 42 – chickenrainshop):

- Lập trình chức năng admin (42)

- Cấu hình prefixes (2":28)

- Lựa chọn layout mặc định cho một controller (7":03) 

- Chọn layout trong beforeFilter để không phải chọn layout nhiều lần trong các controller (10":28)  

- this->request->params (11":01)

- substr  (12":24)

Định dạng URI của các chức năng admin luôn có dạng admin_... Vì vậy, cần thiết lập định dạng cho URI bằng cách cấu hình prefixes trong Config\core.php.

Configure::write('Routing.prefixes', array('admin'));

Thiết lập các action và view cho phần backend, ví dụ thực hiện trên Categories:

Trong CategoriesController có hai action thuộc frontend là menu() và view(); các action còn lại là thuộc backend. Vì vậy, cần thực hiện thêm prefix admin cho các action thuộc backend.

Các view mà có action thuộc backend cũng được đổi tên với prefix là admin.

Nội dung của layout admin.

[admin.ctp]

<?php
$description = 'Chickenrainshop - admin';
?>
<!DOCTYPE html>
<html>
<head>
            <?php echo $this->Html->charset(); ?>
            <title>
                        <?php echo $description ?>:
                        <?php echo $title_for_layout; ?>
            </title>
            <?php
                        echo $this->Html->meta('icon');

                        echo $this->Html->css('cake.generic');

                        echo $this->fetch('meta');
                        echo $this->fetch('css');
                        echo $this->fetch('script');
            ?>
</head>
<body>
            <div id="container">
                        <div id="header">
                                    <h1><?php echo $this->Html->link($description, 'http://local.chickenrainshop'); ?><small> | Chào <strong><?php echo $userInfo['fullname']; ?></strong>! <?php echo $this->Html->link('Thoát', '/logout'); ?></small></h1>
                        </div>
                        <div id="content">

                                    <?php echo $this->Flash->render(); ?>
                                    <?php echo $this->element('admin/menu'); ?>
                                    <?php echo $this->fetch('content'); ?>
                                   
                        </div>
            </div>
</body>
</html>
[Elements\admin\menu.ctp]
 <div class="actions">
            <h3><?php echo __('Menu'); ?></h3>
            <ul>
                        <li><?php echo $this->Html->link(__('Categories'), ['controller' => 'categories', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Books'), ['controller' => 'books', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Coupons'), ['controller' => 'coupons', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Writers'), ['controller' => 'writers', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Comments'), ['controller' => 'comments', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Orders'), ['controller' => 'orders', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Groups'), ['controller' => 'groups', 'action' => 'index']); ?></li>
                        <li><?php echo $this->Html->link(__('Users'), ['controller' => 'users', 'action' => 'index']); ?></li>
            </ul>
</div>

[View\Categories\admin_index.ctp]

<div class="categories index">
            <h2><?php echo __('Categories'); ?></h2>
            <table cellpadding="0" cellspacing="0">
            <thead>
            <tr>
                                    <th><?php echo $this->Paginator->sort('id'); ?></th>
                                    <th><?php echo $this->Paginator->sort('name'); ?></th>
                                    <th><?php echo $this->Paginator->sort('slug'); ?></th>
                                    <th><?php echo $this->Paginator->sort('description'); ?></th>
                                    <th><?php echo $this->Paginator->sort('created'); ?></th>
                                    <th class="actions"><?php echo __('Actions'); ?></th>
            </tr>
            </thead>
            <tbody>
            <?php foreach ($categories as $category): ?>
            <tr>
                        <td><?php echo h($category['Category']['id']); ?>&nbsp;</td>
                        <td><?php echo h($category['Category']['name']); ?>&nbsp;</td>
                        <td><?php echo h($category['Category']['slug']); ?>&nbsp;</td>
                        <td><?php echo h($category['Category']['description']); ?>&nbsp;</td>
                        <td><?php echo h($category['Category']['created']); ?>&nbsp;</td>
                        <td class="actions">
                                    <?php echo $this->Html->link(__('View'), array('action' => 'view', $category['Category']['id'])); ?>
                                    <?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $category['Category']['id'])); ?>
                                    <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $category['Category']['id']), array('confirm' => __('Are you sure you want to delete # %s?', $category['Category']['id']))); ?>
                        </td>
            </tr>
<?php endforeach; ?>
            </tbody>
            </table>
            <p>
            <?php
            echo $this->Paginator->counter(array(
                        'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
            ));
            ?>       </p>
            <div class="paging">
            <?php
                        echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
                        echo $this->Paginator->numbers(array('separator' => ''));
                        echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
            ?>
            </div>
</div>
<div class="actions">
            <ul>
                        <li><?php echo $this->Html->link(__('New Category'), array('action' => 'add')); ?></li>
                        <li><?php echo $this->Html->link(__('List Books'), array('controller' => 'books', 'action' => 'index')); ?> </li>
                        <li><?php echo $this->Html->link(__('New Book'), array('controller' => 'books', 'action' => 'add')); ?> </li>
            </ul>
</div>

Thay vì thiết lập layout trong  từng action, có thể làm một lần tại hàm beforeFilter, bằng cách kiểm tra biến $this->request->params và thiết lập layout cho phù hợp.

[Controller\AppController.php]

            public function beforeFilter() {
                        $this->Auth->allow('confirm','menu', 'index', 'register', 'forgotPassword');
                        $this->set('userInfo', $this->getUser());
                        //pr($this->request->params);
                        if (substr($this->request->params['action'], 0, 6) == 'admin_') {
                                    $this->layout = 'admin';
                        }
            }

[View\Categories\admin_add.ctp]

<div class="categories form">
<?php echo $this->Form->create('Category'); ?>
            <fieldset>
                        <legend><?php echo __('Add Category'); ?></legend>
            <?php
                        echo $this->Form->input('name');
                        echo $this->Form->input('slug');
                        echo $this->Form->input('description');
            ?>
            </fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>

Viết route cho ‘/admin’:

[routes.php]

Router::connect('/', ['controller' => 'books', 'action' => 'index']);

Router::connect('/admin', ['controller' => 'categories', 'action' => 'index', 'admin' => true]);
-----------
Cập nhật 24/7/2017
-----------
Xem thêm:
Tổng hợp các bài viết về Ngu ngơ học làm web