1.1で始めるYii Framework その2 (モデルの作成、CRUD機能の追加)

1.1で始めるYii Framework その1 (環境構築、Yiiインストール、データベース設定)
から引き続き、Yii Frameworkでのブログ作成を行います。

今回は、
2.プロトタイピング
を実施します。


モデルについて

Yii Frameworkは、MVC+DAO/ActiveRecordをベースにアプリケーションを構築します。*1
乱暴に言ってしまうと、各テーブルを元に固まりを作ってアプリを作りましょうね、と認識しています。
(この辺は、まだまだ勉強不足なところもあるので現状での判断)


そこでまずは、DBを構築した後、テーブルごとにモデルを作成。その後メインのテーブルを元にアプリを構築します。
テーブルに付いては、その1で構築済みですが、ER図については下記の通りになります。

本家サイトのER図
http://www.yiiframework.com/images/blog/schema.png

はじめに各テーブルへのDAOとなるモデルを作成します。作成するモデルは以下の通り。

  • 記事を格納するポストテーブル
  • 記事に対するコメントを格納するコメントテーブル
  • 投稿ユーザ情報を格納するユーザテーブル
  • 記事のタグ情報を格納するタグテーブル

モデルの自動生成

モデルに付いては、DBに接続済みなのでyiicツールのシェルモードを使用して自動生成します。
コマンドプロンプトを開き、以下のコマンドを実施します。

D:\pdt\xampp\htdocs\yii\framework>yiic shell D:\pdt\xampp\htdocs\blog\index.php
※、実行後、以下のシェル入力によるインタラクティブモードが起動します。

Yii Interactive Tool v1.0 (based on Yii v1.1rc)
Please type 'help' for help. Type 'exit' to quit.
>>
>>

※、コマンド入力モードで「model テーブル名」を入力して、各テーブルのモデルを作成します。
>> model User
......
>> model Post
......
>> model Tag
......
>> model Comment
......

これで、プロジェクトをリフレッシュすると、D:\pdt\xampp\htdocs\blog\protected\models以下に

が作成されます。
各ファイルの内容を確認すると、DBの項目情報を元に最低限の機能が実装されています。
この実装を元にバリデーションはテーブル間のリレーション情報を追記していきます。

CRUDによるベース機能の実装

上記のインタラクティブモードから、記事投稿機能とコメント入力機能の足場となる機能を生成します。

※、コマンド入力モードで「crud テーブル名」を入力して、各テーブルのモデルを作成します。
>> crud Post
......
>> crud Comment
......

※、生成したら、インタラクティブモードを終了します。
>> exit

再度プロジェクトをリフレッシュして以下のファイルが生成されていることを確認します。

  • コントローラファイル(D:\pdt\xampp\htdocs\blog\protected\controllers)
    • PostController.php
    • CommentController.php
  • ビューファイル(D:\pdt\xampp\htdocs\blog\protected\views)
    • post/create.php
    • post/update.php
    • post/show.php
    • post/list.php
    • post/admin.php
    • post/_form.php
    • comment/create.php
    • comment/update.php
    • comment/show.php
    • comment/list.php
    • comment/admin.php
    • comment/_form.php

CRUDコマンドから、新規・更新・一覧・管理者機能・入力情報管理のビュー項目とそれを操作するコントローラが生成されます。
それぞれのファイルはモデル同様に最低限の機能のみを実装しており、必要機能を追記していきます。
各画面にアクセスします。
http://localhost/blog/index.php?r=post
一覧画面


新規登録画面


更新画面


管理者画面


http://localhost/blog/index.php?r=comment

一覧画面


新規登録画面


管理者画面


各画面での登録・一覧表示・削除ができることを確認します。

ユーザ認証

Yiiでは、アプリケーションの生成時にユーザ認証機能が標準で実装されてます。
実装箇所は

  • D:\pdt\xampp\htdocs\blog\protected\components\UserIdentity.php

内のUserIdentityクラスとなります。標準では固定ユーザのみなので、データベースのユーザテーブルを参照するように仕様変更します。

※、変更前
<?php
	/**
	 * Authenticates a user.
	 * The example implementation makes sure if the username and password
	 * are both 'demo'.
	 * In practical applications, this should be changed to authenticate
	 * against some persistent user identity storage (e.g. database).
	 * @return boolean whether authentication succeeds.
	 */
	public function authenticate()
	{
		$users=array(
			// username => password
			'demo'=>'demo',
			'admin'=>'admin',
		);
		if(!isset($users[$this->username]))
			$this->errorCode=self::ERROR_USERNAME_INVALID;
		else if($users[$this->username]!==$this->password)
			$this->errorCode=self::ERROR_PASSWORD_INVALID;
		else
			$this->errorCode=self::ERROR_NONE;
		return !$this->errorCode;
	}

※、変更後
	private $_id;
	
	/**
	 * Userテーブルから認証を実施。
	 * @return boolean whether authentication succeeds.
	 */
	public function authenticate()
	{
		$user=User::model()->find('LOWER(username)=?',array(strtolower($this->username)));
		if($user===null)
			$this->errorCode=self::ERROR_USERNAME_INVALID;
		else if(md5($this->password)!==$user->password)
			$this->errorCode=self::ERROR_PASSWORD_INVALID;
		else
		{
			$this->_id=$user->id;
			$this->username=$user->username;
			$this->errorCode=self::ERROR_NONE;
		}
		return !$this->errorCode;
	}

	/**
	 * 親クラスのCUserIdentityでは、getIdメソッドではusernameを返すので、オーバーライドしてユーザのidを返すよう変更
	 * @return integer the ID of the user record
	 */
	public function getId()
	{
		return $this->_id;
	}

ユーザ認証の仕組みとして、まずユーザモデルをつかって、該当するユーザのチェックを行います。

  • $user=User::model()->find('LOWER(username)=?',array(strtolower($this->username)));

該当するユーザのデータが有る場合、パスワードのチェックを行います。

  • md5($this->password)!==$user->password

パスワードが一致していたら、ユーザ名、エラーコードをセットします。

  • $this->_id=$user->id;        // _idにpostされたidをセット
  • $this->username=$user->username;  // CUserIdentityより継承
  • $this->errorCode=self::ERROR_NONE; // CBaseUserIdentityより継承

今回はここまで。

その3では、ブログの記事を投稿するための実装を行います。