fuelphpのCRUDテンプレート

デフォルトで生成されるCRUDが気に入らなかったので、自分で作ってみた。

自動生成の不満点は

  1. クラスが継承じゃないので全体を変えたいときに不便
  2. なぜかViewの方ではテンプレートを組み込む形でやっているので、好きなテンプレートエンジンへの移行がしにくいこと
  3. 確認画面がない
  4. createとeditが別々にある
  5. indexでページャーが居ない
  6. モデルにプロパティをひとつ追加した時の変更が大変

というわけでつくりました。

controller/crud.php

[php]
<?php

class Controller_Crud extends Controller {

protected $_modelClassName = NULL;
protected $_inputProperties = array();
protected $_baseUri = "";
protected $_assignParams = array();
protected $_perPage = 20;

/**
*
* @param Request $request
* @param Response $response
*/
public function __construct(Request $request, Response $response) {
parent::__construct($request, $response);
$this->_init();
}

/**
* 初期化。
* ここをオーバーライドして設定する
*
*/
protected function _init(){
$modelClassName = "";
$this->_confirm = true;
$this->_modelClassName = $modelClassName;
$this->_inputProperties = $modelClassName::properties();
$this->_baseUri = "";
$this->_assignParams = array();
$this->_perPage = 20;

}

/**
* 一覧表示画面
* hasNext/hasPrevがあればそれぞれ次のページがある
*
* @param int $page
* @return FuelCoreResponse
*/
public function action_index($page = 1) {
$modelClassName = $this->_modelClassName;
$query = $modelClassName::query();
$count = $query->count();

$query->limit($this->_perPage)
->offset(($page – 1) * $this->_perPage);
$models = $query->get();

$smarty = ParserView_Smarty::forge($this->_baseUri . ‘/index.tpl’)
->set(‘models’, $models)
->set(‘hasNext’, (bool) ($this->_perPage * $page < $count))
->set(‘hasPrev’, (bool) ($page > 1))
->set(‘page’, $page);
return FuelCoreResponse::forge($smarty);
}

/**
* データの編集 or 新規作成
* $id = null で新規作成
* ?bakc=1をつければエラーでもとってきたと判断し、セッションから情報を持ってくる
*
* @param int $id
* @return FuelCoreResponse
*/
public function action_edit($id = null) {
$errors = ”;
$model = $this->_getModel($id);

if (FuelCoreInput::get(‘back’)) {
$errors = FuelCoreSession::get_flash(‘errors’);
$params = FuelCoreSession::get_flash(‘params’);
$this->_setInputParamsToModel($model,$params);
}

$smarty = ParserView_Smarty::forge($this->_baseUri . ‘/edit.tpl’)
->set(‘model’, $model)
->set(‘errors’, $errors);

$this->_assignToSmarty($smarty);

return FuelCoreResponse::forge($smarty);
}

/**
* 確認画面
* $id = null で新規作成
* エラーがあればedit?back=1へリダイレクトする
*
* @param type $id
* @return FuelCoreResponse
*/
public function action_confirm($id = null) {

if (Input::method() != ‘POST’) {
FuelCoreSession::set_flash(‘params’, FuelCoreInput::post());
return FuelCoreResponse::redirect($this->_baseUri .’/edit/’ . $id . "?back=1");
}

$model = $this->_getModel($id);
$val = $this->_getValidate($id);

if (!$val->run()) {
FuelCoreSession::set_flash(‘errors’, $val->show_errors());
FuelCoreSession::set_flash(‘params’, FuelCoreInput::post());
return FuelCoreResponse::redirect($this->_baseUri . ‘/edit/’ . $id . "?back=1");
}

$this->_setInputParamsToModel($model, FuelCoreInput::post());
FuelCoreSession::set(‘params’, FuelCoreInput::post());

$smarty = ParserView_Smarty::forge($this->_baseUri . ‘/confirm.tpl’)
->set(‘model’, $model)
->set(‘inputProperties’, $this->_inputProperties);
$this->_assignToSmarty($smarty);
return FuelCoreResponse::forge($smarty);
}

/**
* 保存画面
* エラーがあればedit?back=1にリダイレクトする
* 保存に成功すればindexにリダイレクトする
*
* @param int $id
* @return FuelCoreResponse
*/
public function action_save($id = null) {
if (Input::method() != ‘POST’ || Input::get(‘back’)) {
FuelCoreSession::set_flash(‘params’, FuelCoreInput::post());
return FuelCoreResponse::redirect($this->_baseUri . ‘/edit/’ . $id . "?back=1");
}
$model = $this->_getModel($id);
$val = $this->_getValidate($id);

if (!$val->run()) {
Session::set_flash(‘errors’, $val->show_errors());
FuelCoreSession::set_flash(‘params’, FuelCoreInput::post());
return FuelCoreResponse::redirect($this->_baseUri . ‘/edit/’ . $id . "?back=1");
}

$this->_setInputParamsToModel($model, FuelCoreInput::post());

if ($model and $model->save()) {
Response::redirect($this->_baseUri);
} else {
Session::set_flash(‘errors’, ‘保存できませんでした’);
FuelCoreSession::set_flash(‘params’, FuelCoreInput::post());
return FuelCoreResponse::redirect($this->_baseUri . ‘/edit/’ . $id . "?back=1");
}

return FuelCoreResponse::redirect($this->_baseUri);
}

/**
* 削除画面
* 削除してindexへリダイレクトする
*
* @param int $id
*/
public function action_delete($id = null) {
$model = $this->_getModel($id);
$model->delete();
Response::redirect($this->_baseUri);
}

/**
* スマーティーにクラス全体のデータをアサインする。
* @param ParserView_Smarty $smarty
*/
private function _assignToSmarty(ParserView_Smarty $smarty){
foreach ($this->_assignParams as $key => $value) {
$smarty->set($key, $value);
}
}

/**
* モデルを返す。
*
* @param int $id
* @return OrmModel
*/
private function _getModel($id = NULL){
$modelClassName = $this->_modelClassName;
if ($id == null) {
return $modelClassName::forge();
}
return $modelClassName::find($id);
}

/**
* バリデーションを返す
* @param int $id
* @return FuelCoreValidation
*/
private function _getValidate($id = NULL){
$modelClassName = $this->_modelClassName;
if ($id == null) {
return $modelClassName::validate(‘create’);
}
return $modelClassName::validate(‘edit’);
}

/**
* 入力許可されたプロパティのみモデルにセットする
*
* @param OrmModel $model
* @param array $params
*/
private function _setInputParamsToModel($model, $params) {
foreach ($this->_inputProperties as $key) {
if (isset($params[$key])) {
$model->set($key, $params[$key]);
}
}
}

}
[/php]

自動生成のものとは画面遷移の流れがちょっと違います。
自動生成のものだと、editでバリデートまでして、その後遷移する形ですが、
自分の作ったのではconfirmでバリデートし、エラーがあればeditに戻る形をとりました。
これは、formでactionに自分のアドレスを書くのに違和感があったからです。それ以外の理由はありません。

できるだけこまかくメソッドに分けたので、多分継承してカスタマイズ・・・ができるはず。

 

4 Responses to fuelphpのCRUDクラス(継承用)をつくってみた

  1. フランキー より:

    コントローラを読み込ませる時にうまく読み込めないんですけど、どうやってるんですか?

  2. wicket より:

    読み込みの問題は、おそらくファイル名と設置場所の問題かな?と思います。
    記事もチョット間違ってたので修正しました。

    fuel/app/classes/controller/curd.php に設置すればロードされるかなと思います。

  3. フランキー より:

    ありがとうございます!

    また、46行目の
    $query = $modelClassName::query();
    の箇所の処理で止まってしまうんですけど
    どのようにすればいいですか?

    初歩的な質問ですみませんが
    よろしくお願いいたします。

  4. フランキー より:

    追記なんですけども、モデルはModel_crudを使ってますか?

    すみませんが宜しくお願いいたします

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>