プレゼンタ

プレゼンタとは?

プレゼンタはビューの生成に必要なロジックを含むクラスです。 コントローラがユーザ入力を処理し、必要なアクションを処理すると、 プレゼンタにビューに必要なデータを取得するように処理を引き継ぎます。 プレゼンタはデータの操作を一切すべきではありませんが、データベースの呼び出しや他のデータの取得、 ビューの生成に必要な準備の操作を含めます。

プレゼンタはオプションです。必要ない場合は、ビュー を直接使用し、表示の前処理のロジックをコントローラに含めることができます。

プレゼンタの作成

最初は APPPATH/classes/presenter/index.php で、空のプレゼンタを作成します:

class Presenter_Index extends Presenter
{
}

そして、app/views/index.php に対応するビューを作成します:

<h1><?php echo $title; ?></h1>

<ul>
<?php
	foreach ($articles as $a)
	{
		echo '<li>'.$a->title.'</li>';
	}
?>
</ul>

ビューの名前
プレゼンタとそのビューはデフォルトでは同じ名前を共有します。 プレゼンタ Presenter_Index のビューは app/views/index.php になります。 アンダースコアはクラスと同じように、つまり、ビュー Presenter_Some_Thing は、 app/views/some/thing.php になります。
このデフォルトの動作は、そのビューを使うプレゼンタの中で、静的でない $_view プロパティにプレゼンタの中でビュー名 (サフィックスなしで) 設定するか、プレゼンタの生成時に独自のビュー名を渡すことで オーバーライトできます。

最後に、プレゼンタをコントローラから生成します:

$presenter = Presenter::forge('index');

これですべてを設定しました; しかし、まだデータがビューに渡されていません。 $title の文字列と $articles の配列を渡す必要があります。 プレゼンタにこのデータを与える view() メソッドを追加します:

class Presenter_Index extends Presenter
{

	public function view()
	{
		$this->title = 'Testing this Presenter thing';

		$this->articles = Model_Articles::find('all');
	}
}

これで完了です。

コードの中でビューとプレゼンタは交換可能です。コントローラのアクションからプレゼンタを返すことも、 テーマのパーシャルとしてプレゼンタをセットし、ページテンプレートのセクションにアサインすることもできます。プレゼンタの基本的な API は ビューと互換性があります。これは、大きなコードのオーバーホールなしに、 ビューとプレゼンタを簡単に交換することを可能にします。.

関数をビューに渡す

プレゼンタからビューに特定の関数を渡すには、匿名関数または クロージャ を使います:

// プレゼンタの中
class Presenter_Index extends Presenter
{

	public function view()
	{
		// 値を返すクロージャをセット
		$this->somevar = function() { return "somevalue"; };

		// これも同様に機能します
		$this->set('othervar', function() { return "othervalue"; });

		// 引数付きのクロージャには、エンコーディングを避けるために set_safe を使います
		$this->set_safe('echo_upper', function($string) { echo strtoupper($string); });
	}
}

// presenter view の中で使える:
echo $somevar, $othervar;   // 出力: "somevalue" "othervalue"
$echo_upper('this string'); // 出力: "THIS STRING"

クロージャはフィルタリングに関して値と同様に扱われます。 値を返すクロージャの場合、set() メソッドを使えば、 その値はフィルタリングの設定に従ってエンコードされます。 もし、上記の例のような修飾子の場合や、 返される値がエンコードされるべきでないクロージャの場合は、 set_safe() メソッドを使うか、 set() メソッドの第 3 引数に false を指定して下さい。

クロージャがフィルタされないことを期待しているレガシーアプリケーションでは、 アプリケーションの設定ファイル config.php を編集し、次のキーを追加します:

/**
 * クロージャをフィルタするかどうか
 */
'filter_closures'  => false,

セキュリティ

ビューと同じように動作します。プレゼンタでセットされたものはすべて、オフにしない限り、出力エンコードされます。 ビューで使うのと同じようにプレゼンタでも set($name, $value, $encode) メソッドが使えます。 詳細は、 ビューのセキュリティのセクション にあります。

高度な使い方

他のメソッド

同じビューを解析する別の方法がある場合は、デフォルトの view() メソッド以外に複数のメソッドをプレゼンタに追加することができます。 そうするためには、第 2 パラメータにメソッド名を指定した Presenter::forge() メソッドを追加します:

// 上記の例からプレゼンタ上の other_method() メソッドを呼ぶ
$presenter = Presenter::forge('index', 'other_method');

before と after メソッド

いくつかのデータをプレゼンタのすべてのメソッドで使う必要がある場合、before() または after() メソッドをコントローラと同様に追加します。

ビューの変更

デフォルトでは $this->_view にビューオブジェクトがアサインされます。 プレゼンタに独自の set_view() メソッドを作成し、 $this->_view にオブジェクトをセットすることで置き換えることができます。
しかし、そのオブジェクトはプロパティを設定でき (テンプレートのデータとして使われます)、解析されたコンテンツをレンダリングし返す __toString() マジックメソッドを持たなくてはなりません。 言い換えると、View クラスの振る舞いとの互換性が必要です。
ビューの名前は $this->_view プロパティから取得できます。

別のビューファイル、または既存のビューオブジェクトを使う

forge() メソッドの第 4 引数を指定すると、プレゼンタのインスタンスに対して別のビューを使い、 どのビューを読み込むかを決定する自動機構を使わないように指示することもできます:

// 'index' ビューの代わりに 'other/index' ビューを使う
$presenter = Presenter::forge('index', 'other_method', null, 'other/index');

// ビューオブジェクトを直接渡すこともできる
$view = View::forge('other/index');
$presenter = Presenter::forge('index', 'other_method', null, $view);

ビューへのアクセス

プレゼンタの外部からビューオブジェクトにアクセスするには、 get_view() メソッドを使用します。

他の名前空間から、または Presenter_ 接頭辞のつかないプレゼンタを使う

これらを使用する場合、名前空間を含む、完全なクラス名で forge() を使う必要があります。 その場合、デフォルトの命名規則はしばしば期待したように動作しませんので、 $_view プロパティまたはまたはカスタムビュー名を渡すことが推奨されます。