コピペ用の簡易View生成コマンド(KYview)

cakeを使うと、ロジックの部分はすごく簡単にかけるようになるんだけど、DBのカラム数が多いとViewにセットした変数を記述していくのも結構一苦労。
bakeとか使えよって感じだけど、簡易管理画面以外はbake使わないし、bakeの生成するviewは余分な情報が多すぎる。

欲しいのは、コントローラからセットしたものを表示する箇所だけ。もしくはフォームでPOSTするinputの箇所。
その箇所のリストがあってコピペしてViewのhtmlに貼ってくだけあればもう少し作業効率上がるんじゃないかと思って、作ってみました。これにあまり時間をかけてもしょうがないので簡単なものを作った。複雑な箇所や、今は僕に必要なさそうなものは実装してません。
DBカラムみていい感じのコードを出力してくれるわけではなく、あまり空気を読まずシンプルなパターンのみ出力するだけの補助ツールです。名付けてKYview

さて、これを実装する前に、モデルやテーブルを指定してテーブル情報を取ってくる必要があります。
まずはこの箇所だけの説明から。

App::import('Model');
$tempModel = new Model(array('name' => $modelname, 'table' => $tablename, null));
$fields = $tempModel->schema();

これだけでできちゃいます。モデルクラスの引数にテーブルを指定するだけ。あとはschemaメソッドで配列にスキーマ情報がセットされます。
後はこれを使って、自分のviewに必要そうな感じに整形して出力するだけ。
kyviewでは、3パターンの出力をサポートしてます。


まずは下準備として下記のようなテーブルがあるとします

CREATE TABLE `hoge` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `hoge1` INT,
  `hoge2var` VARCHAR(255),
  `hoge3text` TEXT,
  `hogedate` DATE,
  `created` DATETIME,
  `modified` DATETIME,
  PRIMARY KEY (`id`)
)
CHARACTER SET utf8;


このカラムに対する簡易viewを生成します。
kyviewの引数は、すべて必須で、順にモデル名、テーブル名、表示パターン、となります。
表示パターンは数字で、下記の3つです。

表示パターンに1をセット : $viewinfo[modelname][column]
表示パターンに2をセット : $form->value(modelname.column)
表示パターンに3をセット : $form->text("modelname.column", $options=array("size" => "30", "maxlength" => "30"));


まずは表示パターン1。
これはコントローラから$this->set( 'viewinfo', $this->MODEL->find() ) などという場合のViewの記載パターンです。
cd app/vendors/shells
に移動して
./cake kyview Order hoge 1
を実行すると(コマンドのソースは最後に記載します)、下記の出力になります

var $uses = array(Order); in controller
var $useTable = array(hoge); in model

<?php echo h( $viewinfo['Order']['id'] ); ?>
<?php echo h( $viewinfo['Order']['hoge1'] ); ?>
<?php echo h( $viewinfo['Order']['hoge2var'] ); ?>
<?php echo h( $viewinfo['Order']['hoge3text'] ); ?>
<?php echo h( date( "Y/m/d", $time->fromString( $viewinfo['Order']['hogedate'])) ); ?>
<?php echo h( date( "Y/m/d", $time->fromString( $viewinfo['Order']['created'])) ); ?>
<?php echo h( date( "Y/m/d", $time->fromString( $viewinfo['Order']['modified'])) ); ?>

Dont forget  var $helpers = array('Time'); in controller

最初の2行はモデルやコントローラに指定するモデル名やテーブル名の出力です。
その次の行からViewのコピペ用出力になります。ちょっとだけ空気を読んでDBのカラムがdateやdatetime型の場合は、表示を2008/1/2のような形にしてくれます。表示形式を変えたければ "Y/m/d"の箇所を変えてください。
最後の行は、dateやdatetime型があると、timeヘルパーを利用するため($time->fromStringの箇所)、コントローラにヘルパーでTimeを指定し忘れないように注意するための記述です。timeが入る場合のみ表示されます。


次に、表示パターン2。
これは確認画面などでPOSTしたデータを表示する場合などに使います。
cd app/vendors/shells
に移動して
./cake kyview Order hoge 2
を実行すると(コマンドのソースは最後に記載します)、下記の出力になります
Viewの所だけ抜き出します。

<?php echo h( $form->value("Order.id") ); ?>
<?php echo h( $form->value("Order.hoge1") ); ?>
<?php echo h( $form->value("Order.hoge2var") ); ?>
<?php echo h( $form->value("Order.hoge3text") ); ?>
<?php echo h( date( "Y/m/d", $time->fromString( $form->value("Order.hogedate") )) ); ?>
<?php echo h( date( "Y/m/d", $time->fromString( $form->value("Order.created") )) ); ?>
<?php echo h( date( "Y/m/d", $time->fromString( $form->value("Order.modified") )) ); ?>


最後に表示パターン3。
これはフォーム画面のinput項目用に使います。
cd app/vendors/shells
に移動して
./cake kyview Order hoge 3
を実行すると(コマンドのソースは最後に記載します)、下記の出力になります
Viewの所だけ抜き出します。

<?php echo $form->text( "Order.id", $options = array( "size" => "30", "maxlength" => "30" )); ?>
<?php echo $form->text( "Order.hoge1", $options = array( "size" => "30", "maxlength" => "30" )); ?>
<?php echo $form->text( "Order.hoge2var", $options = array( "size" => "30", "maxlength" => "30" )); ?>
<?php echo $form->textarea( "Order.hoge3text", $options = array( "size" => "30", "maxlength" => "30" )); ?>
<?php echo $form->text( "Order.hogedate", $options = array( "size" => "30", "maxlength" => "30" )); ?>
<?php echo $form->text( "Order.created", $options = array( "size" => "30", "maxlength" => "30" )); ?>
<?php echo $form->text( "Order.modified", $options = array( "size" => "30", "maxlength" => "30" )); ?>

カラムがtext型のみtextarea出力となります。それ以外はすべてtext(input type=text)となります。
オプションで入力エリアのサイズと最大文字数を指定してます。ここはカラムごとに異なりますので後で適宜変更してください。


さて、最後にkyview.phpソースコードです。出力を自分用にカスタマイズするのも難しくないと思いますので、使いたい人は適宜変更してみてください。
下記の箇所にファイルを生成してください。
app/vendors /shells/kyview.php

<?php
class KyviewShell extends Shell {

    function main() {

		/* 引数のチェック */
		$modelname = $this->args[0];
		$tablename = $this->args[1];
		$param = $this->args[2];

		if( empty($modelname) || empty($tablename) || empty($param) ){
			echo "Error: argment is modelname , tablename, param_number\n";
			echo 'param_number 1: $viewinfo[modelname][column]' . "\n";
			echo 'param_number 2 : $form->value(modelname.column)' . "\n";
			echo 'param_number 3 : $form->text("modelname.column", $options=array("size" => "30", "maxlength" => "30"));' . "\n\n";
			exit;
		}


		/* 該当モデルのクラスを読み込み */
		App::import('Model');
		$tempModel = new Model(array('name' => $modelname, 'table' => $tablename, null));
		$fields = $tempModel->schema();

		print 'var $uses = array(' . $modelname . ');' . " in controller\n";
		print 'var $useTable = array(' . $tablename . ');' . " in model\n\n\n";

		$dateflag = 0;

		foreach($fields as $key => $value){
			if($param == 3){
				/* カラムの型がtextであればフォームはtextareaにする */
				if($value['type'] === 'text'){
					$type= 'textarea';
				}else{
					$type= 'text';
				}
				echo '<?php echo $form->' . $type . '( "' . $modelname . '.'. $key . '", $options = array( "size" => "30", "maxlength" => "30" )); ?>' . "\n";

			}elseif($param == 2){
				/* カラムの型がdatetime, date型であれば、2008/9/10のような表示にする */
				if( $value['type'] === 'datetime' || $value['type'] === 'date' ){

					echo '<?php echo h( date( "Y/m/d", $time->fromString( $form->value("' . $modelname . '.' . $key . '") )) ); ?>' . "\n";
					$dateflag = 1;
				}else{
					echo '<?php echo h( $form->value("' . $modelname . '.' . $key . '") ); ?>' . "\n";
				}


			}else{
				/* カラムの型がdatetime, date型であれば、2008/9/10のような表示にする */
				if( $value['type'] === 'datetime' || $value['type'] === 'date' ){

					echo '<?php echo h( date( "Y/m/d", $time->fromString( $viewinfo[\'' . $modelname . '\'][\'' . $key . '\'])) ); ?>' . "\n";
					$dateflag = 1;
				}else{
					echo '<?php echo h( $viewinfo[\'' . $modelname . '\'][\'' . $key . '\'] ); ?>' . "\n";
				}

			}

		}

		if($dateflag){
			echo "\n" . 'Dont forget  var $helpers = array(\'Time\'); in controller' . "\n";
		}

    }

}
?>

実装時間とこのブログを書いてる時間が同じぐらいになってきたw