Edited at

初めてPHPのフレームワーク(Yii)を使ってみる その4

More than 3 years have passed since last update.

まずは復習を兼ねて、新規会員登録フォームを作ってみます。

その後、UserとUserProfileのバリデーションなどを作り上げてみたいと思います。



新規会員登録フォームを作る


UserモデルのCRUD実装コードを自動生成する

Giiを使ってUserモデルのCRUD機能を生成する

Gii->Crud Generator->Model ClassにUserを入力してpreview->Generate


UserモデルのbeforeSave()をオーバーライドする

パスワードはデータベースに登録する前にハッシュをかけるので、beforeSave()をオーバーライドする


User.php

...

protected function beforeSave() {
if(parent::beforeSave()) {
$this->password = CPasswordHelper::hashPassword($this->password);
return true;
} else {
return false;
}
}
...


_form.phpの編集とconfirm.phpの作成

特に難しいこともなく、その3のUserProfileと同じように作成、編集する

反復練習大事

ただし_form.phpにはメールアドレスとパスワードの確認入力欄を追加している


/views/user/_form.php

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'user-form',
// Please note: When you enable ajax validation, make sure the corresponding
// controller action is handling ajax validation correctly.
// There is a call to performAjaxValidation() commented in generated controller code.
// See class documentation of CActiveForm for details on this.
'enableAjaxValidation'=>false,
)); ?>

<p class="note">Fields with <span class="required">*</span> are required.</p>

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

<div class="row">
<?php echo $form->labelEx($model,'mailaddr'); ?>
<?php echo $form->textField($model,'mailaddr',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'mailaddr'); ?>
</div>

<div class="row">
<?php echo $form->labelEx($model,'verifymailaddr'); ?>
<?php echo $form->textField($model,'verifymailaddr',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'verifymailaddr'); ?>
</div>

<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password',array('size'=>60,'maxlength'=>32)); ?>
<?php echo $form->error($model,'password'); ?>
</div>

<div class="row">
<?php echo $form->labelEx($model,'verifypassword'); ?>
<?php echo $form->passwordField($model,'verifypassword',array('size'=>60,'maxlength'=>32)); ?>
<?php echo $form->error($model,'verifypassword'); ?>
</div>

<div class="row buttons">
<?php echo CHtml::submitButton('確認画面へ', array('name' => 'confirm')); ?>
</div>

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

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



/views/user/confirm.php

<?php

/* @var $this UserController */
/* @var $model User */

$this->breadcrumbs=array(
'Users'=>array('index'),
$model->id,
);

$this->menu=array(
array('label'=>'List User', 'url'=>array('index')),
array('label'=>'Create User', 'url'=>array('create')),
array('label'=>'Update User', 'url'=>array('update', 'id'=>$model->id)),
array('label'=>'Delete User', 'url'=>'#', 'linkOptions'=>array('submit'=>array('delete','id'=>$model->id),'confirm'=>'Are you sure you want to delete this item?')),
array('label'=>'Manage User', 'url'=>array('admin')),
);
?>

<h1>記入内容確認</h1>

<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
//'id',
'mailaddr',
'password',
//'auth',
),
)); ?>
<!-- 以下を追加 -->
<div class="form">
<?php
echo CHtml::statefulForm();
echo CHtml::submitButton('戻る', array('name' => 'back'));
echo CHtml::submitButton('次へ', array('name' => 'finish'));
?>
</form>
</div>



UserController.phpの編集

同様に、UserController.phpも編集する

変えたところはaccessRules()とactionCreate(),actionUpdate()


/controllers/UserController.php

...

public function accessRules()
{
return array(
/*array('deny', // ログインしている会員は新規登録できない
'actions'=>array('create'),
'users'=>array('@'),
),*/

array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('create','index','view'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('update'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}

...

public function actionCreate()
{
$model=new User;

// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);

if(isset($_POST['confirm']))
{
$model->attributes=$_POST['User'];
if($model->validate())
{
$this->setPageState('create', $_POST['User']);
$this->render('confirm', compact('model'));
return;
}
} else if(isset($_POST['back']))
{
$model->attributes = $this->getPageState('create');
}
else if(isset($_POST['finish']))
{
$model->attributes = $this->getPageState('create');
if($model->save()) {
// ここで今作ったアカウントで自動ログインする
$id = new UserIdentity($model->mailaddr, $password);
$id->authenticate();
if($id->errorCode===UserIdentity::ERROR_NONE) {
Yii::app()->user->login($id, 0);
}
$this->redirect(Yii::app()->baseUrl.'?r=userProfile/create');
}
}
$this->render('create', compact('model'));
}

/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/

public function actionUpdate()
{
$model=$this->loadModel(Yii::app()->user->id);

// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);

if(isset($_POST['confirm']))
{
$model->attributes=$_POST['User'];
if($model->validate())
{
$this->setPageState('update', $_POST['User']);
$this->render('confirm', compact('model'));
return;
}
} else if(isset($_POST['back']))
{
$model->attributes = $this->getPageState('update');
}
else if(isset($_POST['finish']))
{
$model->attributes = $this->getPageState('update');
if($model->save()) {
$this->redirect(Yii::app()->baseUrl);
}
}
$this->render('update', compact('model'));
}

...



バリデーションを作成する

User.phpとUserProfile.phpのrules()を書き換えて検証ルールを宣言する

(まだとりあえず感があるが...)

これは公式サイトがわかりやすい

検証ルールの宣言

メールアドレスとパスワードに関しては、確認欄を設けているので、verifymailaddrとverifypasswordを新たにプロパティに加えて、rules()にも記述しておく

確認欄の追加の仕方はここがわかりやすかった

verify password yii framework


User.php

...

class User extends CActiveRecord
{

public $verifymailaddr;
public $verifypassword;

...

public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('mailaddr, password', 'required'),
array('mailaddr', 'length', 'max'=>128),
array('mailaddr', 'unique', 'message' => Yii::t('app',"This user's email adress already exists.")),
array('verifymailaddr', 'compare', 'compareAttribute'=>'mailaddr'),
array('password', 'length', 'max'=>32),
array('verifypassword', 'length', 'max'=>32),
array('verifypassword', 'compare', 'compareAttribute'=>'password'),
array('mailaddr', 'email'),
// The following rule is used by search().
// @todo Please remove those attributes that should not be searched.
array('id, mailaddr, password, auth', 'safe', 'on'=>'search'),
);
}

...



Userprofile.php

...

public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('id, firstname, lastname, kana_firstname, kana_lastname, zipcode, address, phone1', 'required'),
array('firstname, lastname, kana_firstname, kana_lastname, post, phone1, phone2, fax', 'length', 'max'=>20),
array('kana_firstname, kana_lastname, kana_corporation', 'match', 'pattern'=>'/^[ァ-ヶヲ-゚ー]+$/u'),
array('phone1, phone2, fax', 'match', 'pattern'=>'/^([+]?[0-9 -]+)$/'),
array('corporation, kana_corporation', 'length', 'max'=>50),
//array('zipcode, deliverable_zipcode', 'length', 'max'=>10),
array('zipcode, deliverable_zipcode', 'match', 'pattern'=>'/^[0-9]{3}[-]?[0-9]{4}$/'),
array('address, deliverable_address', 'length', 'max'=>100),
array('email2', 'length', 'max'=>128),
array('email2', 'email'),
// The following rule is used by search().
// @todo Please remove those attributes that should not be searched.
array('id, firstname, lastname, kana_firstname, kana_lastname, corporation, kana_corporation, post, zipcode, address, phone1, phone2, fax, email2, deliverable_zipcode, deliverable_address, point', 'safe', 'on'=>'search'),
);
}
...