intro
Zend_Aclによるアクセス制御を行います。
デモサイトより動作を確認できます。
デモサイトより動作を確認できます。
1.テーブルの作成
この記事では以下のSQLを使用しました(MySQL)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CREATE TABLE members ( id integer auto_increment NOT NULL PRIMARY KEY, role_id integer NOT NULL, nick_name varchar(100) NOT NULL, email varchar(200) NOT NULL ); CREATE TABLE roles ( id integer auto_increment NOT NULL PRIMARY KEY, role_name varchar(20) NOT NULL, privileges varchar(10) NOT NULL ); CREATE TABLE messages ( id integer auto_increment NOT NULL PRIMARY KEY, member_id integer NOT NULL, message text NOT NULL ); |
2.コントローラの作成
以下のように
application/constorllers/MessageController.php
ファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
<?php require_once 'My/Controller/Simple.php'; require_once APP_BASE . '/models/Roles.php'; require_once APP_BASE . '/models/Members.php'; require_once APP_BASE . '/models/Messages.php'; require_once APP_BASE . '/models/forms/MessageForm.php'; require_once APP_BASE . '/models/acls/MessageAcl.php'; class MessageController extends My_Controller_Simple { protected $_session_name = "Message"; protected $_table_class = "Messages"; protected $_form_class = "MessageForm"; protected $_acl = null; protected function _getOutputFilter($data = null) { $messages = new Messages(); return $messages->getOutputFilter($data); } public function getForm() { $form = parent::getForm(); $form->getElement('member_id')->setValue($this->getSession()->member_id); return $form; } public function getLoginForm() { $members = new Members(); $member_options = $members->getOptions(); $form = new Zend_Form(array( 'method' => 'post', 'action' => $this->_helper->url->url(array('action'=>'index')), 'elements' => array( 'member' => array('select', array( 'required' => true, 'label' => 'member', 'multiOptions' => $member_options, 'validators' => array( array('inArray', true, array(array_keys($member_options))) ), )), 'submit' => array('submit', array( 'label' => 'Login', 'decorators' => array( 'ViewHelper', array('HtmlTag', array('tag' => 'dt', 'class' => 'submit')) ) )) ), )); return $form; } public function init() { parent::init(); $this->_acl = new MessageAcl(); } public function preDispatch() { parent::preDispatch(); $action = $this->getRequest()->getActionName(); $session = $this->getSession(); if ($action != 'index' && $action != 'deny') { if (!isset($session->role)) { $this->_helper->redirector('index'); } else if (!$this->_acl->isAllowed($session->role, null, $action)) { $this->_helper->redirector('deny'); } } $this->view->name = "message"; $this->view->of = $this->_getOutputFilter(); } public function indexAction() { // Select member $this->view->action = $this->getRequest()->getActionName(); $form = $this->getLoginForm(); $session = $this->getSession(); if ($this->getRequest()->isPost()) { if ($form->isValid($_POST)) { $values = $form->getValues(); $members = new Members(); $member = $members->find($values['member'])->current(); if ($member) { $role = $member->findParentRoles(); if ($role) { $session->member_id = $values['member']; $session->role = $role->role_name; $this->_helper->redirector('list'); } } } } $this->view->form = $form; return $this->render('form'); } public function denyAction() { } } |
3.モデルの作成
以下のように
以下のように
以下のように
application/models/Messages.php
ファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php require_once 'Zend/Db/Table/Abstract.php'; require_once APP_BASE . '/models/Members.php'; class Messages extends Zend_Db_Table_Abstract { protected $_name = 'messages'; public function getOutputFilter($data = null) { $members = new Members(); $member_options = $members->getOptions(); // add other filters $filters = array( 'member_id' => array(array('ArrayValue', $member_options)) ); $of = new Zend_Filter_Input($filters, null, $data); $of->addFilterPrefixPath('My_Filter', 'My/Filter/'); return $of; } } |
以下のように
application/models/forms/MessageForm.php
ファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php require_once 'Zend/Form.php'; require_once APP_BASE . '/models/Members.php'; class MessageForm extends Zend_Form { public function __construct() { $members = new Members(); $member_options = $members->getOptions(); parent::__construct(); $member_id = $this->createElement('hidden', 'member_id'); $member_id->setRequired(true) ->addFilter('stringTrim') ->addValidator('inArray', false, array(array_keys($member_options))); $message = $this->createElement('textarea', 'message'); $message->setLabel('message') ->setAttribs(array('cols'=>'40', 'rows'=>'10')) ->setRequired(true) ->addFilter('stringTrim') ->addValidator('stringLength', false, array(1,1000)); $this->addElements(array( $member_id, $message )); } } |
以下のように
application/models/acls/MessageAcl.php
ファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php require_once 'Zend/Acl.php'; require_once 'Zend/Acl/Role.php'; class MessageAcl extends Zend_Acl { public function __construct() { $admin = new Zend_Acl_Role('admin'); $user = new Zend_Acl_Role('user'); $guest = new Zend_Acl_Role('guest'); $this->addRole($admin); $this->addRole($guest); $this->addRole($user, $guest); $this->allow($admin); $this->allow($guest, null, array('list', 'detail')); // user is allowed list and view also $this->allow($user, null, array('add')); } } |
4.ビューの作成
以下のように
以下のように
以下のように
以下のように
以下のように
application/views/scripts/message/list.phtml
ファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<h1><?= $this->translate($this->name . '.title.list') ?></h1> <?php if (!$this->list) : ?> <span><?= $this->translate($this->name . 'label.no_data') ?></span> <?php else : ?> <a href="<?=$this->url(array('action'=>'add'))?>"> <?= $this->translate($this->name . '.label.new') ?></a> <table> <?php $this->header = true; ?> <?php foreach($this->list as $row) : $values = $row->toArray(); $this->of->setData($values); if ($this->header) : ?> <tr> <?php foreach($values as $key => $value) : ?> <th><?= $this->translate($key) ?></th> <?php endforeach; ?> <th><?= $this->translate('detail') ?></th> <th><?= $this->translate('edit') ?></th> <th><?= $this->translate('delete') ?></th> <?php $this->header = false; ?> </tr> <?php endif; ?> <tr> <?php foreach($values as $key => $value) : ?> <td><?= $this->of->$key ?></td> <?php endforeach; ?> <td><a href="<?=$this->url(array('action'=>'detail'))?>?id=<?=$values['id']?>"> <?= $this->translate('detail') ?></a></td> <td><a href="<?=$this->url(array('action'=>'update'))?>?id=<?=$values['id']?>"> <?= $this->translate('edit') ?></a></td> <td><a href="<?=$this->url(array('action'=>'delete'))?>?id=<?=$values['id']?>"> <?= $this->translate('delete') ?></a></td> </tr> <?php endforeach; ?> </table> <span><?= $this->translate($this->name . '.label.max') ?></span> <?php endif; ?> |
以下のように
application/views/scripts/message/form.phtml
ファイルを作成します。
1 2 |
<h1><?= $this->translate($this->name . '.title.' . $this->action) ?></h1> <?= $this->form ?> |
以下のように
application/views/scripts/message/detail.phtml
ファイルを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<h1><?= $this->translate($this->name . '.title.detail') ?></h1> <?php if ($this->values) : ?> <?php $this->of->setData($this->values); ?> <dl> <?php foreach($this->values as $key => $value) : ?> <dt><?= $this->translate($key) ?></dt> <dd><?= $this->of->$key ?></dd> <?php endforeach; ?> </dl> <?php endif; ?> <?php if ($this->form) : ?> <?= $this->form ?> <?php endif; ?> |
以下のように
application/views/scripts/message/finish.phtml
ファイルを作成します。
1 2 3 |
<h1><?= $this->translate($this->name . '.title.finish.' . $this->action) ?></h1> <a href="<?=$this->url(array('action'=>'list'))?>"> <?= $this->translate('back') ?></a> |
以下のように
application/views/scripts/message/deny.phtml
ファイルを作成します。
1 2 3 4 5 6 7 |
<h1><?= $this->translate($this->name . '.title.deny') ?></h1> <div><?= $this->translate($this->name . '.label.deny') ?></div> <a href="<?=$this->url(array('action'=>'index'))?>"> <?= $this->translate('login') ?></a> <br /> <a href="<?=$this->url(array('action'=>'list'))?>"> <?= $this->translate('back') ?></a> |
5.確認
Webサーバにアクセスし、選択したメンバーにより編集などができないことを確認してください。
履歴
日付 | 内容 |
---|---|
2008/5/9 | 公開 |
2008/5/9 | MessageAcl のアクション名が一部間違っていました(viewをdetailへ変更) |