Yii Framework Forum: Yii初心者のための基本的なことまとめ - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Yii初心者のための基本的なことまとめ 学んだことを共有、蓄積していく場 Rate Topic: -----

#1 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 26 January 2011 - 01:36 AM

Yii初心者のための基本的な知識を共有する場としてトピックをたてました

質問、疑問に対する返答の場ではなく、
Yiiの基本部分をピックアップして、大多数が扱える情報を投稿していくトピックになれば幸いです
ささいなことでもかまわないので、遠慮なく書き込んでください


( 最終更新日 2013-08-26 )
0

#2 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 28 January 2011 - 12:02 PM

単純なページネーションの例

Controller :
public function actionIndex() {
    $criteria = new CDbCriteria();
    $pages = new CPagination(Hoge::model()->count($criteria));

    $pages->pageSize = 10; // 1ページに何件表示するか
    $pages->applyLimit($criteria);
    $models = Hoge::model()->findAll($criteria);

    $this->render('index', array(
        'pages' => $pages,
        'models' => $models,
    ));
}

View :
<?php foreach($models as $model): ?>
    // 表示の処理
<?php endforeach; ?>

// ページネーションを表示
<?php $this->widget('CLinkPager', array(
    'pages' => $pages,
)) ?>

CLinkPagerを実行すると、assetsディレクトリにpager.cssが自動生成されます
デザインを変更したい場合は、webroot/css下などにコピペして、そのファイルを編集します
最後に
<?php $this->widget('CLinkPager', array(
    'pages' => $pages,
    'cssFile' => Yii::app()->request->baseUrl . '/css/pager.css', // 追加
)) ?>

を追加し、assetsディレクトリに自動生成されたpager.cssのディレクトリごと削除します
cssFileを設定することで、CLinkPager関連のファイルが自動生成されなくなります

関連リンク
[Class Reference] CPagination
[Class Reference] CLinkPager
[Yii Playground] BasicPager Pagination
0

#3 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 05 March 2011 - 09:24 AM

2つのModelを1つのFormで作る

例えば、掲示板などでtopic, forumと、2つのテーブルを作ったとします
topicにはタイトル、forumにはコメントなどが入っているとして、その両方をまとめて保存する方法です

Controller
public function actionCreate()
{
	$topic = new Topic;
	$forum = new Forum;
	if (isset($_POST['Topic'], $_POST['Forum'])) {
		$topic->attributes = $_POST['Topic'];
		$forum->attributes = $_POST['Forum'];

		$valid = $topic->validate();
		$valid = $forum->validate() && $valid;

		$transaction = $topic->dbConnection->beginTransaction(); // transaction
		if ($valid) {
			try {
				$topic->save(false);
				$forum->topic_id = $topic->id;
				$forum->save(false);
				$transaction->commit(); // commit
				$this->redirect(array('somewhere'));

			} catch (Exception $e) {
				$transaction->rollBack(); // rollBack
			}
		}
	}
	$this->render('create', array(
		'topic' => $topic,
		'forum' => $forum
	));
}

View
<?php echo CHtml::form(); ?>
<?php echo CHtml::errorSummary(array($topic, $forum)); ?>
	<?php // topic, forumのinput ?>
	<?php echo CHtml::submitButton('書き込む'); ?>
</form>

基本的に難しいことは何もしておらず
まずtopic, forumの値にvalidate()を通して、両方がTRUEならsave(false)するだけです
(save括弧内のfalseはvalidateしないってことです )
topicModelをsaveした時点で、topic.idが得られますので、その値をforum.topic_idに入れています
また、トランザクション処理も追加してみました

ViewはerrorSummary()に配列でモデル名を入れるだけです

関連リンク
[Wiki] How to use a single form to collect data for two or more models?
[Guide] アクティブレコード
[Forum] Transaction on multiple AR
0

#4 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 07 March 2011 - 09:27 AM

controller, action名を取得する方法

controller名取得
  • Yii::app()->controller->id
  • $this->id
  • $this->uniqueId ( モジュールが絡んでくると「moduleID/controllerID」、その他は「controllerID」 )

action名取得
  • Yii::app()->controller->action->id
  • $this->action->id

$this->から始まるものはcontroller, viewのみ使用でき
Yii::app()->で始まるものは、ある程度どこでも使用できます

関連リンク
[Forum] How to get current controller & action
[Class Reference] CController
0

#5 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 22 March 2011 - 05:37 AM

省略化したfunction名を利用して、入力作業を軽減させる

オフィシャルのWikiに載ってたやつです

CHtml::encode()を、h()
Yii::app()をapp()などに省略できるようにします

ルートディレクトリのindex.phpに
require('path/to/globals.php');を追加して、globals.phpにいろいろ省略したいものを書いていきます

注意点としては
  • globals.phpをアクセスが制限されているディレクトリに置くこと
  • 再利用可能な拡張機能としてリリースする予定のコンポーネントでこれらの省略化したfunction名を使用しないこと
です

関連リンク
[Wiki] Use shortcut functions to reduce typing
0

#6 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 28 March 2011 - 04:28 AM

アプリケーション全体を通しての定数

yiicツールを使ってアプリケーションを作成したあと
protected/config/main.phpで全体のいろいろな設定を行いますが
アプリケーション全体を通しての定数もここで作成できます

config/main.php
// application-level parameters that can be accessed
// using Yii::app()->params['paramName']
'params'=>array(
    // this is used in contact page
    'adminEmail'=>'webmaster@example.com',
),

上記のコードはmain.phpの下部に書かれていて
配列のkeyに名前、valueに値を入れ、コメントでも書かれているように
Yii::app()->params['paramName']; で値を得ることができます

$adminEmail = Yii::app()->params['adminEmail']; // "webmaster@example.com" を返す

また、Yiiに最初から用意されているdemoのblogでは
'params'=>require(dirname(__FILE__) . '/params.php'),

として、config/main.phpの同じディレクトリにparams.phpを作成し、そこに定数をまとめています

config/params.php
?php
return array(
    'title'=>'My Yii Blog',
    'adminEmail'=>'webmaster@example.com',
    'postsPerPage'=>10,
    'recentCommentCount'=>10,
    'tagCloudCount'=>20,
    'commentNeedApproval'=>true,
    'copyrightInfo'=>'Copyright © 2009 by My Company.',
);

どちらが良いかは個人それぞれの判断でしょうか
あと、一つ前のPostでも述べた省略化functionで
function param($name) 
{
    return Yii::app()->params[$name];
}

を指定すると、Yii::app()->params['adminEmail'];をparam('adminEmail');に略すことも可能です

関連リンク
[Wiki] Setting and getting systemwide static parameters
0

#7 User is offline   mocapapa 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 428
  • Joined: 04-January 09
  • Location:Tokyo, JAPAN

Posted 28 March 2011 - 06:42 PM

View Postjamband, on 26 January 2011 - 02:21 AM, said:

メッセージの日本語化とカスタマイズ方法

'name' => 'sample',
'language' => 'ja',

とするとエラーメッセージ、ページネーション、バリデートメッセージやらが日本語になります
ただ、あらかじめ用意された日本語メッセージなので、ややおかしな文章になっているものもあります

日本語がおかしな場合はご指摘いただければ次回のリリースに入れたいと思いますので、よろしくお願いします。:)
0

#8 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 28 March 2011 - 09:58 PM

個人的にですが、だいたいの基盤があれば
あとは、「それぞれが好みの日本語に直す」で、OKだと思います :)
0

#9 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 03 April 2011 - 01:36 AM

簡単なCRUDの例

英単語帳みたいなサンプルアプリケーションを作ります
左に英単語、右にその日本語訳、みたいなのです ( 例: yes - はい )

  • データベース名: english
  • テーブル名: word ( フィールド : id, eng, jpn )

wordテーブルのモデルだけGiiを使って生成し
Controller, Viewを、自前で実装していきます。まず、少しだけWord.phpの修正
<?php
class Word extends CActiveRecord
{
	...
	public function rules()
	{
		return array(
			array('eng', 'unique'), // 追加
			array('eng, jpn', 'required'),
			array('eng, jpn', 'length', 'max'=>50),
		);
	}

	public function attributeLabels()
	{
		return array(
			'id' => 'ID',
			'eng' => '英単語', // 修正
			'jpn' => '日本語訳',  // 修正
		);
	}
}

登録した英単語が重複しないようにuniqueを追加
また、attributesLabelsをわかりやすい名前に修正

次に、WordController.phpを作っていきます
<?php
class WordController extends Controller {

	public function actionIndex()
	{
		$c = CDbCriteria();
		$c->order = 't.id DESC';
		$models = Word::model()->findAll($c);

		$this->render('index', compact('models'));
	}
	
	public function actionCreate()
	{
		$model = new Word;
		$this->save($model);
	}
	
	public function actionView($id)
	{
		$model = $this->loadModel($id);
		$this->render('view', compact('model'));
	}
	
	public function actionUpdate($id)
	{
		$model = $this->loadModel($id);
		$this->save($model);
	}
	
	public function actionDelete($id)
	{
		$this->loadModel($id)->delete();
		$this->redirect(array('somewhere'));
	}
	
	protected function save($model)
	{
		if (isset($_POST['Word']))
		{
			$model->attributes = $_POST['Word'];
			if ($model->save())
				$this->redirect(array('somewhere'));
		}
		$this->render('_form', compact('model'));
	}
	
	protected function loadModel($id)
	{
		$model = Word::model()->findByPk($id);
		if ($model === null)
			throw new CHttpException(404, 'データがありません');

		return $model;
	}
}

actionIndex()
wordテーブルのすべてのデータを、並び順をidのDESCにして、views/words/index.phpに渡しています

actionCreate()
まずWordのインスタンスを作成し、$modelに代入します
次の$this->save()は自作のメソッドで
「POSTリクエストがあった場合、データを保存し、保存が完了すればsomewhereページへリダイレクトする」
という基本的なものですが、actionUpdate()でも同様のことをするのでまとめています
また
// これと
$model->attributes = $_POST['Word']

// これは
$model->eng = $_POST['Word']['eng'];
$model->jpn = $_POST['Word']['jpn'];
同等のことをやっています

actionView($id)
まず、$this->loadModel($id)ですが、これも自作のメソッドで
$_GET['id']の値を取得して、wordテーブルから1件データを取得するメソッドです
actionView($id), actionUpdate($id), actionDelete($id)で利用するのでまとめています
また、データがない場合は、例外を投げて「データがありません」と表示させています

actionUpdate($id)
これはactionCreate()とactionView($id)を混ぜたものと考えてください
INSERTとUPDATEの違いは、「new」してるものはINSERT、find系を使っているものはUPDATEです

actionDelete($id)
$_GET['id']の値を取得して、wordテーブルから1件データを取得し、それを削除しています

次にViewを作っていきます
ファイルはとりあえず3つ用意しました。_form.phpは共通で使うものです

  • _form.php
  • index.php
  • view.php

_form.php ( actionCreate, actionUpdateで使用 )
フォームを作っています
errorSummaryはバリデーションエラーをまとめて表示させるものです
<h1><?php echo $this->action->id; ?></h1>
<?php echo CHtml::form(); ?> 
<?php echo CHtml::errorSummary($model); ?>
	<?php echo CHtml::activeTextField($model, 'eng', array('maxlength' => 64)); ?> 
	<?php echo CHtml::activeTextField($model, 'jpn', array('maxlength' => 64)); ?> 
	<?php echo CHtml::submitButton($model->isNewRecord?'追加する':'更新する'); ?> 
</form>

index.php
<h1><?php echo $this->action->id; ?></h1>
<p><?php echo CHtml::link('追加', array('create')); ?></p>
<?php foreach ($models as $model): ?>
<?php echo CHtml::encode($model->eng); ?>  
<?php echo CHtml::encode($model->jpn); ?>  
<?php echo CHtml::link('表示', array('view', 'id' => $model->id)); ?> 
<?php echo CHtml::link('編集', array('update', 'id' => $model->id)); ?> 
<?php echo CHtml::link('削除', array('delete', 'id' => $model->id), array('confirm' => '削除してもよろしいですか?')); ?> 
<br />
<?php endforeach; ?>

view.php
<h1><?php echo $this->action->id; ?></h1>
<?php echo CHtml::encode($model->eng); ?> 
<?php echo CHtml::encode($model->jpn); ?>

こまかな部分は省いていますが、だいたいこんな感じです
MVCで共通しているところは、重複するものはまとめることと ( まとめ過ぎも危ういかもですが... )
今回の例ではデータの取得がシンプルだったのでControllerでやっていますが
ModelでやれるべきことはModelでやったほうがControllerの見通しもよくなります
何をどこに書くかはこちらこちらを参考にしてください
また、自分も初心者なので、ここはこうしたほうが良いというものがあれば、是非言ってください
0

#10 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 03 April 2011 - 11:11 AM

ウィジェットのデフォルト値を一元管理する

なかなかYiiのバージョン毎にどんな機能が追加されているのかに、ついていけてないですが
version 1.1.3以降では、ウィジェットのパラメータをconfig/main.phpで一元管理できるようになっているみたいです

例えばCLinkPagerをさまざまな場所で使用しているとして
でも、デザインやパラメータなどはほぼ一緒だったりすると
一つ一つの場所で同じようなパラメータを何度も書くはめになります
それを解消できる、ひとつの手段ですね
大規模な開発になればなるほど、考えるべきところではないでしょうか
'components'=>array(
	'widgetFactory'=>array(
		'widgets'=>array(
			'CLinkPager'=>array(
				'maxButtonCount'=>5,
				'cssFile'=>false,
			),
	                ...
また、基本をconfig/main.phpで書いても
それぞれの場所で上書きできるようになっています

関連リンク
[Guide] ウィジェットをグローバルにカスタマイズする
0

#11 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 06 April 2011 - 01:50 PM

メールアドレス、パスワードでのログイン認証

こちらを参考に少々アレンジして
メールアドレス、パスワードでのログイン認証のサンプルを作成してみました
追加、変更に使用したファイルは4つです

  • protected/components/UserIdentity.php
  • protected/models/LoginForm.php
  • protected/controllers/siteController.php
  • protected/views/site/login.php

UserIdentity.php
<?php
class UserIdentity extends CUserIdentity {

	private $_id;
	public function authenticate()
	{
		$record = Users::model()->findByAttributes(array('email' => $this->username)); // 'username'を'email'に変更
		if ($record === null)
			$this->errorCode = self::ERROR_USERNAME_INVALID;
		else if ($record->password !== sha1('jdf4387fadadf78ad8976hfafdou' . $this->password)) // CakePHP風
			$this->errorCode = self::ERROR_PASSWORD_INVALID;
		else
		{
			$this->_id = $record->id;
			$this->username = $record->username;
			$this->errorCode = self::ERROR_NONE;
		}
		return !$this->errorCode;
	}
	
	public function getId()
	{
		return $this->_id;
	}
}

LoginForm.php
<?php
class LoginForm extends CFormModel {

	public $email; // $usernameをすべて$emailに変更
	public $password;
	public $rememberMe;
		
	public function rules()
	{
		return array(
			array('email, password', 'required'),
			array('email', 'email'), // 追加
			array('rememberMe', 'boolean'),
			array('password', 'authenticate'),
		);
	}
	
	public function attributeLabels()
	{
		return array(
			'email' => 'メールアドレス',
			'password' => 'パスワード',
			'rememberMe' => '保存する',
		);
	}
	
	public function authenticate($attribute, $params)
	{
		if (!$this->hasErrors())
		{
			$identity = new UserIdentity($this->email, $this->password);
			$identity->authenticate();
			if ($identity->errorCode === CUserIdentity::ERROR_NONE)
			{
				$duration = $this->rememberMe ? 3600*24*30 : 0; // 30 days
				Yii::app()->user->login($identity, $duration);
			}
			else
				$this->addError('password', 'メールアドレス、またはパスワードが違います');
		}
	}
}

siteController.php ( ActionLogin() )
public function actionLogin()
{
	$model = new LoginForm;
	if (isset($_POST['LoginForm']))
	{
		$model->attributes = $_POST['LoginForm'];
		if ($model->validate())
			$this->redirect(Yii::app()->user->returnUrl);
	}
	$this->render('login', array('model' => $model));
}

login.php
<?php echo CHtml::form(); ?> 
<?php echo CHtml::errorSummary($model, false); ?>
	<?php echo CHtml::activeLabel($model, 'email'); ?><br />
	<?php echo CHtml::activeTextField($model, 'email'); ?><br />
	<?php echo CHtml::activeLabel($model, 'password'); ?><br />
	<?php echo CHtml::activePasswordField($model, 'password'); ?><br />
	<?php echo CHtml::activeCheckBox($model, 'rememberMe'); ?> <?php echo CHtml::activeLabel($model, 'rememberMe'); ?><br />
	<?php echo CHtml::submitButton('ログイン'); ?>
</form>

0

#12 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 06 April 2011 - 11:07 PM

テーマ変更

themes下にテーマを置き
protected/config/main.phpにthemeを追加

return array(
	'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
	'name'=>'sample',
	'theme' => 'pepper',
	...

関連リンク
Yii Themes ( テーマ配布サイト )
[Guide] テーマ
0

#13 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 07 April 2011 - 02:17 AM

actionコードの再利用

さまざまなControllerで使用するactionを
protected/components/actions下にまとめる、という記事がWikiに載っていたのでテストします
コードはこちらを見ていけばわかるかと思います

サンプルとして、よくあるcreateのactionを使用しています
それをprotected/components/actions下に
さまざまなControllerで使える形に変更し、実装していきます ( create.php )

Step 1 - Creating the Action
CActionを継承して、Create Classを作成し、run()メソッドを実装していきます

run()メソッドの一部
$controller = $this->getController(); // controllerを取得
$model_class = ucfirst($controller->getId()); // controller名の一文字目を大文字にしたものをModel名に

そのあとは、それをインスタンスしてcreateのactionと同じように実装していきます

Step 2 - Declare the action on the Controller
作成したactionを使いたい場合、特定のControllerでactions()メソッドを作成します
コードはStep 2を見てください

application.components.actions.create
ttp://example.com/index.php?r=controller/create という意味です

あとは、createのviewを作成して
どこかから、createのviewのリンクにいけば
protected/components/actions/create.phpが実行されます

また、Final Notesのような形にすると、Create Classのrun()メソッドで
$model_class = ucfirst($controller->getId());
の代わりに
class Create extends CAction {

	public $model_name; // 追加
	public function run()
	{
		$controller = $this->getController();
		if (isset($_POST[$this->model_name]))
		{
			$model->attributes = $_POST[$this->model_name];
			...
という風にもできるみたいです

関連リンク
[Wiki] Actions code reuse with CAction
0

#14 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 09 April 2011 - 10:14 PM

確認画面を挟んだフォームを作る

入力画面 -> 確認画面 -> 完了!って流れです
いくつかやり方があるかと思いますが、Yiiっぽい?、わりとスマートなものを選びました
ひとつの参考としてみて下さい

( wordテーブルにはid, eng, jpnというカラムがあるとします )

Controller
public function actionCreate()
{
	$model = new Word;
	if (isset($_POST['confirm']))
	{
		$model->attributes = $_POST['Word'];
		if ($model->validate())
		{
			$this->setPageState('create', $_POST['Word']);
			$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())
			$this->redirect(array('somewhere'));
	}
	$this->render('create', compact('model'));
}

views/create.php
<h1><?php echo $this->action->id; ?></h1>
<?php echo CHtml::statefulForm(); ?> 
<?php echo CHtml::errorSummary($model, false); ?>
	<?php echo CHtml::activeTextField($model, 'eng', array('maxlength' => 64)); ?> 
	<?php echo CHtml::activeTextField($model, 'jpn', array('maxlength' => 64)); ?> 
	<?php echo CHtml::submitButton('confirm', array('name' => 'confirm')); ?> 
</form>

views/confirm.php
<h1><?php echo $this->action->id . ' - confirm'; ?></h1>
<?php echo CHtml::statefulForm(); ?> 
	<?php echo CHtml::encode($model->eng); ?>  
	<?php echo CHtml::encode($model->jpn); ?>  
	<?php echo CHtml::submitButton('back', array('name' => 'back')); ?> 
	<?php echo CHtml::submitButton('finish', array('name' => 'finish')); ?> 
</form>

流れとしては、create.phpでconfirmボタンが押されたら、まずvalidateし
trueの場合、POST['Word']の値を保持し、confirm.phpへ移動
confirm.phpにて、backボタンを押された場合
保持していたPOST['Word']の値を$model->attributesに返し、create.phpに戻る
confirm.phpにて、finishボタンを押された場合
保持していたPOST['Word']の値を$model->attributesに返し、save()メソッドを実行...

ControllerでsetPageState(), getPageState()を使う場合
ViewではセットとしてCHtml::statefulForm()を使う必要があります

関連リンク
[Class Reference] CController::setPageState()
[stackoverflow] Yii multi page form wizard best practice
[Wiki] How to work with flash messages
[Extension] wizard-behavior
0

#15 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 10 April 2011 - 11:31 AM

CController, CActiveRecordを拡張して、独自の共通Classを作成する

すべてのController, Modelで共有できそうなメソッドを
protected/components下に置いて、それを継承してController, Modelを作成すると
コード量が減ったり、管理しやすくなったりします

Controllerに関してはスケルトンアプリケーションを作成するとすでに作られているので
サンプルとして、CActiveRecordを拡張したActiveRecord.phpを作成して、簡単なコードを書いてみます

protected/components/ActiveRecord.php
class ActiveRecord extends CActiveRecord
{
	protected function beforeSave()
	{
		if ($this->hasAttribute('modified'))
		{
			if ($this->isNewRecord)
				$this->created = new CDbExpression('NOW()');
			else
				$this->modified = new CDbExpression('NOW()');
		}
		return parent::beforeSave();
	}
	...

上記のサンプルは、データを保存する前に
そのテーブルにmodifiedというFieldがあった場合
新規保存に関してはcreated Fieldに現在の時刻を挿入
新規でない場合にはmodified Fieldに現在の時刻を挿入する、というメソッドです

たくさんのテーブルがあるアプリケーションを作成していて
そのテーブルの半分くらいにcreated, modified Fieldがある場合などに便利かと思います
その他、まだまだアイディア次第でいろんなことに活用できますので是非

関連リンク
[Wiki] Extending common classes to allow better customization
[Class Reference] CTimestampBehavior ( 上記と同じようなことをbehaviorでやっています )
0

#16 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 10 April 2011 - 11:19 PM

Modelにおける初期のクエリパラメータを指定する

例えば、あるModel内でfindを作るときに
やたら'condition' => 't.user_id = ' . Yii::app()->user->id
というconditionを書いているならdefaultScope()を使用して簡略化できます
( select, order, limitなども指定可 )

public function defaultScope()
{
	return array(
		'condition' => 't.user_id = ' . Yii::app()->user->id,
	);
}

defaultScope()はあるModelにおける初期のクエリパラメータを指定できるもので
そのModelのすべてのfindに反映されます ( SELECT時のみ、INSERT, UPDATE, DELETE時には無視されます )

また、特定のfindにはdefaultScope()を反映させたくない場合は、resetScope()を使います
Hoge::model()->resetScope()->findAll(); // resetScope()はv1.1.2以降で使用可

※備考
defaultScope()で指定したconditionがあったとして
さらにfindでconditionを指定した場合、WHERE部分はANDで繋がれます
また、defaultScope()と全く同じものをfindで指定した場合には上書きされます

関連リンク
[Guide] デフォルトスコープ ( ページ下部 )
[Class Reference] defaultScope()
0

#17 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 31 May 2011 - 05:39 AM

YiiとjQueryの基本的なこと

基本的にYiiはjQueryが絡んでくるコードを書くと
assetsディレクトリにjs, cssなどのファイルがパッケージとして書き込まれ
HTMLのhead部分にはjs, cssのタグを、body末尾部分にはjsのコードなどを自動で生成します

ここでは、それらとは別に
独自で、js, cssのファイルを呼び出したり、コードを挿入したりする方法をまとめてみます
( 書き込む場所はview, またはlayout )

Yiiがcoreで保持しているjquery.js, jquery-ui.jsを呼び出す :
<?php Yii::app()->clientScript->registerCoreScript('jquery'); ?>
<?php Yii::app()->clientScript->registerCoreScript('jquery.ui'); ?>
( v1.1.7以降では、Yii::app()->clientScript->registerPackage('jquery'); でも同様 )

hoge.jsを呼び出す :
<?php Yii::app()->clientScript->registerScriptFile(Yii::app()->request->baseUrl . '/js/hoge.js'); ?>

jQueryのコードを追加 :
<?php Yii::app()->clientScript->registerScript('hogeId', "$('div').fadeOut();"); ?>
( jQueryのコードをregisterScript()で追加すると、coreのjquery.jsが自動で呼ばれます )

また、registerScriptFile()は第2引数で、registerScript()は第3引数で、配置指定もできます
無記入の場合は、registerScriptFile()はHTMLのhead部分にタグが、
registerScript()はbody末尾部分にコードが生成されます ( 詳しくはClass Referenceを参考に )

関連リンク
[Class Reference] CClientScript
0

#18 User is offline   jamband 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 75
  • Joined: 05-November 10

Posted 09 June 2011 - 11:43 AM

メッセージの日本語化とカスタマイズ方法

YiiをDLすると、framework下にmessagesディレクトリがあります
この中には、さまざまな言語に対応できるように
あらかじめいろんな言語に訳したファイルがたくさんあります ( 日本語は「ja」です )
framework/messages/ja/yii.phpを開くと感覚的にわかりますが
「'英語表記' => '日本語表記'」となっています

例えば、「yiic webapp D:\xampp\htdocs\sample」でスケルトンアプリケーションを作成した後、
sample/protected/config/main.php内で
'name' => 'sample',
'language' => 'ja',

とするとエラーメッセージ、ページネーション、バリデートメッセージやらが日本語になります
ただ、あらかじめ用意された日本語メッセージなので、ややおかしな文章になっているものもあります
カスタマイズするにはframework/messages内のjaフォルダをコピーして
sample/protected/messages/に置き、このファイル内を変更していきます

最後に、sample/protected/config/main.php内に下記を追加
'components' => array(
    'coreMessages' => array(
        'basePath' => 'protected/messages', // もしくは 'protected/mesages' 部分をnull
  ),

framework/messages/ja/yii.php内を直接変更しない理由
framework以下はコアなので変更してはいけない ( バージョンアップを行う際、書き換えられる危険があります )

関連リンク
[Wiki] How to customize Yii core messages?
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users