第12章 管理画面のユーザ一覧と編集

前回までの成果物:

本章から読み始める人のために、前回までの成果物を以下に置いておきます。

ダウンロードはこちらからお願いします

  •  htdocs-chap11.zip をxamppのhtdocs以下に展開してください。
  • また2つのSQLファイルをyii のデータベース上へインポートしてください。

また一部動作のために設定を変更していただく必要がある箇所があります。

protected/config/main.php を開いてください。以下の箇所について

		// chap7: メール送信ライブラリを追加
		'mailer'=>array(
			    'class' => 'application.extensions.mailer.EMailer',
			    'From' => 'yii.juncheng@gmail.com', // 送信者のアドレス
			    'FromName' => 'yii-juncheng',// 名前
			    'CharSet' => 'iso-2022-jp',  //文字コード
			    'Encoding' => '7bit',
			    'Mailer'=>'smtp',
			    'Port'=>'587',
			    'SMTPSecure'=>'tls',
			    'Host'=> 'smtp.gmail.com',
			    'SMTPAuth' => true,
			    'Username' => 'yii.juncheng@gmail.com', // gmailのメールアドレスがユーザ名となる
			    'Password' => 'unko9314',                // ここにGmailのアドレスを入力する
		),

最後の2箇所のUsername Password をご自身のgmailのアカウントの情報に書き換えてください。(SMTPやポートの情報などの情報がわかっている場合は別のメールサーバーでも問題ありません)

またデータベースを0章の環境設定と異なる設定にした場合は、以下の部分も修正が必要です。

		// uncomment the following to use a MySQL database
		'db'=>array(
			    'connectionString' => 'mysql:host=localhost;dbname=yii',// dbname=yiiに変更する
			    'emulatePrepare' => true,
			    'username' => 'root',
			    'password' => 'unko9314', // ここを0章で設定したmysqlのパスワードに変更する
			    'charset' => 'utf8',
		),

もしデータベースの名称をyii にしていない場合は、dbname=の隣の文字を変更してください。またpasswordを本サイトと異なるパスワードに設定している場合も変更を行ってください。


今回の目標:

本章では、ユーザの一覧を表示するようなページを管理画面に追加します。第8章でメッセージボードを作成した際に、CActiveDataProvider なるものが出てきましたが、データの一覧を表示するのに便利なので、再びこいつを利用したいと思います。また更に各ユーザのデータを管理者によって編集できるようにします。


メニューの追加:

いつもと同じくメニューの追加を行います。views/layouts/main.php を変更します。

array('label'=>'ユーザ一覧', 'url'=>array('/admin/user'), 'visible'=>Yii::app()->user->isAdmin), // chap12

これをメニュー一覧の部分に追加しましょう。変更後は以下のようになるはずです。

	<div id="mainmenu">
		<?php $this->widget('zii.widgets.CMenu',array(
			'items'=>array(
				    array('label'=>'ホーム', 'url'=>array('/site/index')),
				    array('label'=>'当サイトについて', 'url'=>array('/site/page', 'view'=>'about')),
				    array('label'=>'お問い合わせ', 'url'=>array('/site/contact')),
				    array('label'=>'ユーザ登録','url'=>array('/site/registration'),'visible'=>Yii::app()->user->isGuest),
    				array('label'=>'メッセージ閲覧','url'=>array('/site/bbs'),), // chap8
				    array('label'=>'メッセージ投稿','url'=>array('/user/bbs'),'visible'=>Yii::app()->user->isUser), // chap8
				    array('label'=>'プロフィール編集', 'url'=>array('/user/profile'), 'visible'=>!Yii::app()->user->isGuest), // chap9
				    array('label'=>'ユーザ一覧', 'url'=>array('/admin/user'), 'visible'=>Yii::app()->user->isAdmin), // chap12
				    array('label'=>'ログイン', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
				    array('label'=>'ログアウト', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
			),
		)); ?>
	</div>

 


ユーザ一覧画面の作成:

先ほどのユーザ一覧ページへのリンクは 「/admin/user」でした。ですので対応するアクション名はuserになりますのでactionUser のメソッドを追加します。ここでは8章の時と同じようにCActiveProviderを使って一覧の表示機能を実現しています。ここではUserのモデルに対してidの順番に表示をせよという命令を書いています。ビューファイルはprotected/views/admin/user.php としました。

	// chap12: ユーザ一覧のページ
	public function actionUser() {
		    $dataProvider = new CActiveDataProvider('User',array('criteria'=>array('order'=>'id')));
    		$this->render('user',array('dataProvider'=>$dataProvider));
	}

またコントローラの先頭部分でアクセス制限の処理にもuserアクションに対する許可を追加します。

	// アクセスルール
	public function accessRules()
	{
    	return array(
    		// 一般ユーザに対して以下に列挙するactionの実行を許可する
			    array('allow',
				          'actions'=>array('index',
				                           'user'), // chap12: user
				          'expression'=>'$user->isAdmin',
			    ),
			    // 上記のルールに適合しないすべてのユーザを排除
			    array('deny',
				          'users'=>array('*'), // *: 全ユーザ ?: 匿名ユーザ @: 認証済みのユーザ
			         ),
		    );
	}

次に以下の2つのビューファイルを作成しましょう。

user.php はユーザ一覧のページのビューファイルで、一方 user_table.php は表示される各々のデータに対してどのようなHTMLで表示するかを定義した部分です。

  • protected/views/admin/user.php
<?php
$this->pageTitle=Yii::app()->name . ' - ユーザ一覧';
$this->breadcrumbs=array(
	    'ユーザ一覧',
);
?>

<h1>ユーザ一覧</h1>
<table>
<tr>
    <td>ID</td>
    <td>名前</td>
    <td>E-mail</td>
    <td>編集</td>
</tr>
<?php $this->widget('zii.widgets.CListView', array('dataProvider'=>$dataProvider,'itemView'=>'user_table')); ?>
</table>
  • protected/views/admin/user_table.php 
<tr>
    	<td><?php echo $data->id;?></td>
	    <td><?php echo $data->name;?></td>
	    <td><?php echo $data->email;?></td>
	    <td><a href="/admin/editUser/id/<?php echo $data->id;?>">編集</a></td>
</tr>

 

これでとりあえず一覧する機能は完成しました。

chap12-1

 

次に画面の「編集」を押すと指定したユーザのデータを編集できるフォームに遷移するようにします。なお「編集」のリンクのアドレスは http://localhost/admin/editUser/id/ユーザID という形式になっています。


 ユーザデータ編集機能:

次にユーザのデータ編集機能を追加します。追加するメソッド名は上記のURLに対応して、actionEditUser() になります。

まずはじめにこのアクションに対するアクセス権を与えておきます。accessRules() のメソッドに以下のようにeditUserのアクションへのアクセス権を与えるようにリストに追加します。

	// アクセスルール
	public function accessRules()
	{
  	return array(
    		// 一般ユーザに対して以下に列挙するactionの実行を許可する
			    array('allow',
				          'actions'=>array('index',
				                           'user', // chap12: user
				                           'editUser'), // chap12: editUser
				          'expression'=>'$user->isAdmin',
			    ),
			    // 上記のルールに適合しないすべてのユーザを排除
			    array('deny',
				          'users'=>array('*'), // *: 全ユーザ ?: 匿名ユーザ @: 認証済みのユーザ
			    ),
		  );
	}

次にactionEditUser のメソッドを定義します。9章~10章で作ったプロフィール編集の機能のコードがほとんど再利用できますが、管理者メニューからのユーザデータの編集であるため、ユーザのロール(role) 認証状態の項目(valid)も編集できるように変更しました。

またユーザのIDの指定が誤っている場合なども考慮して、正しくユーザの情報が取得できない状況では、例外処理を行っています。

	// chap12: ユーザ編集のページ
	public function actionEditUser() {
    		try {
			        // 更新成功の可否
			        $update = false;
			        // ユーザのデータを取得する
			        if(!isset($_GET['id']))
				            throw new Exception('ユーザのIDが指定されていません');
			        $id = intval($_GET['id']);
			        $user = User::model()->findByPk($id);
			        if(!isset($user))
				            throw new Exception('このようなユーザは存在しません');
			
        			// ajax
		        	if(isset($_POST['ajax']) && $_POST['ajax']==='edit-form')
		        	{
				            echo CActiveForm::validate($user);
				            Yii::app()->end();
			        }
        			// フォームに対して入力があった場合
			        if(isset($_POST['User'])) {
				            // ユーザからの入力を処理
				            if(isset($_POST['User']['email']))
					                $user->email = $_POST['User']['email'];
				            if(isset($_POST['User']['name']))
					                $user->name = $_POST['User']['name'];
				            if(isset($_POST['User']['newPassword']))
					                $user->newPassword = $_POST['User']['newPassword'];
				            if(isset($_POST['User']['image']))
					                $user->image = CUploadedFile::getInstanceByName('User[image]');
				            if(isset($_POST['User']['role']))
					                $user->role = $_POST['User']['role'];
				            if(isset($_POST['User']['valid']))
					                $user->valid = $_POST['User']['valid'];
		            		// データを保存する場合:
				            if($user->validate()) {
					                $user->save();
					                $update = true;
				            }
        }
		        	// フォームviewを表示
			        $this->render('edit_user',array('model'=>$user,'update'=>$update));
		    } catch(Exception $ex) {
			        throw new CHttpException(503,$ex->getMessage());
	    }
	}

それにともなってビューファイルは以下のようになります。

protected/views/admin/edit_user.php を作って以下のような内容にします。

rolevalid を編集できるように変更したので、そのフォームを追加しています。ドロップダウンリストはdropDownList というメソッドで出力が可能です。ドロップダウンリストを表示する際に、各項目の表示用の名前と実際のvalue の組み合わせを表す配列を第3引数に与えてやる必要があります。第4引数は出力html用のオプションを指定したい場合に使います。

<?php
// chap9
$this->pageTitle=Yii::app()->name . ' - ユーザ情報編集';
$this->breadcrumbs=array(
	'ユーザ情報編集',
);
?>

<h1>ユーザ情報編集</h1>

<div class="form">
<?php if($update == true):?>
    <p><font color="red">更新に成功しました</font></p>
<?php endif;?>
<?php $form=$this->beginWidget('CActiveForm', array(
	    'id'=>'edit-form',
	    'enableAjaxValidation'=>true, // ajaxで処理
	    'clientOptions'=>array(
		    'validateOnSubmit'=>true,
    	),
	    'htmlOptions'=>array('enctype'=>'multipart/form-data'), 
)); ?>

	<p class="note"><span class="required">*</span>の項目は入力が必須となります</p>
	<p class="note">HTMLタグは自動的に変換されます。</p>

	<?php echo $form->errorSummary($model); ?>

	<div class="row">
		<?php echo $form->labelEx($model,'email'); ?>
		<?php echo $form->textField($model,'email'); ?>
		<?php echo $form->error($model,'email'); ?>
	</div>
	
	<div class="row">
		<?php echo $form->labelEx($model,'name'); ?>
		<?php echo $form->textField($model,'name'); ?>
		<?php echo $form->error($model,'name'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'newPassword'); ?>
		<?php echo $form->textField($model,'newPassword'); ?>
		<?php echo $form->error($model,'newPassword'); ?>
	</div>
	
	<div class="row">
		<?php echo $form->labelEx($model,'role'); ?>
		<?php echo $form->dropDownList($model,'role',array('0'=>'一般ユーザ','1'=>'管理者'),array()); ?>
		<?php echo $form->error($model,'role'); ?>
	</div>
	
	<div class="row">
		<?php echo $form->labelEx($model,'valid'); ?>
		<?php echo $form->dropDownList($model,'valid',array(false=>'未認証',true=>'認証済み'),array()); ?>
		<?php echo $form->error($model,'valid'); ?>
	</div>
	
	<div class="row">
		<?php echo $form->labelEx($model,'image'); ?>
		<?php echo $form->fileField($model,'image'); ?>
		<?php echo $form->error($model,'image'); ?>
	</div>
	
	<div class="row">
	    <img src="<?php echo Yii::app()->request->baseUrl . '/' . $model->avatar; ?>">
	</div>

	<div class="row buttons">
		<?php echo CHtml::submitButton('データを編集する'); ?>
	</div>

<?php $this->endWidget(); ?>

</div><!-- form -->

 

以上で管理者画面から任意のユーザのデータを編集できるようになりました。


今回の成果物:

今回の成果物を以下のリンクに置いておきます。

ダウンロードはこちらからお願いします

  • htdocs-chap12.zip : ソースコード
  • user.sql , bbs.sql : データベースのダンプファイル。(今回は特にデータベース構造をいじっていないので、前回から内容は変わっていません)