cakephp2.doc_082
最終投稿日:2019年11月20日
< 入力画面 >
項目1:フリーコメント 必須
項目2:画像
項目3:画像
項目4:画像
※項目2~項目4は、最低1つの画像選択が必須となる。
※登録できる画像タイプは[gif][png][jpag]のみ
※画像のサイズは1M未満
< 確認画面 >
選択した画像の削除が行える
※この際画像がゼロになった場合は入力画面へ遷移する。
< 登録画面 >
画像カラム[image1][image2][image3]へは、選択の位置に関係なく1から順に登録する。
[ Controller ]
<?php
App::uses('AppController', 'Controller');
//Folder クラス使用
App::uses( 'Folder','Utility');
//File クラス使用
App::uses( 'File','Utility');
//Bootstrap3用プラグイン
CakePlugin::load("Hoge");
class MysamplesController extends AppController {
public $name = "Mysamples";
//サンプルで使用したテーブル
public $uses = array("Image");
//MyImageControlle コンポーネント使用
public $components = array("Session","MyImageControlle");
//Bootstrap3用ヘルパー使用
public $helpers = array('Html', 'Form','Hoge.BootstrapCss');
function beforeFilter(){
parent::beforeFilter();
}
/**************************************************************************
* 入力画面
***************************************************************************/
function image_index(){
//トークン作成
$token = sha1(session_id() . mt_rand());
$this->Session->write("token",$token);
$this->set("token",$token);
//念のため画像セッション削除
$this->Session->delete("image1");
$this->Session->delete("image2");
$this->Session->delete("image3");
}
/**************************************************************************
* 確認画面
***************************************************************************/
function image_confirm(){
//トークンチェック
if(empty($this->request->data["Image"]["token"])
or $this->request->data["Image"]["token"] != $this->Session->read("token")){
$this->redirect(array("controller"=>"mysamples","action"=>"image_index"));
}
$this->set("token",$this->Session->read("token"));
//仮の画像保管場所
$user = $this->Auth->user();
$tmpPath = "/home/hoge/www/cake2612/img/tmp_image/".$user["username"]."/";
//画像1にファイルがセットされていたらセッションに保存する
if(!empty($this->request->data["Image"]["image1"]["name"])){
$this->Session->write("image1",$this->request->data["Image"]["image1"]);
}
//画像2にファイルがセットされていたらセッションに保存する
if(!empty($this->request->data["Image"]["image2"]["name"])){
$this->Session->write("image2",$this->request->data["Image"]["image2"]);
}
//画像3にファイルがセットされていたらセッションに保存する
if(!empty($this->request->data["Image"]["image3"]["name"])){
$this->Session->write("image3",$this->request->data["Image"]["image3"]);
}
//セッションに画像があるかチェック(これで常に[入力]⇔[確認]画面を往復しても値が確保できる)
if($this->Session->read("image1") != null){
$this->request->data["Image"]["image1"] = $this->Session->read("image1");
}
if($this->Session->read("image2") != null){
$this->request->data["Image"]["image2"] = $this->Session->read("image2");
}
if($this->Session->read("image3") != null){
$this->request->data["Image"]["image3"] = $this->Session->read("image3");
}
/******************************************************
* バリデーションチェック
*
* エラーがあっても、正常な画像は仮画像として保存する
*******************************************************/
$this->Image->set($this->request->data);
if(!$this->Image->validates()){
//バリデーションエラーとなり、画像パスが登録されているセッションを削除
if(!empty($this->Image->validationErrors["image1"]) and $this->Session->read("image1") != null){
$this->Session->delete("image1");
}
if(!empty($this->Image->validationErrors["image2"]) and $this->Session->read("image2") != null){
$this->Session->delete("image2");
}
if(!empty($this->Image->validationErrors["image3"]) and $this->Session->read("image3") != null){
$this->Session->delete("image3");
}
//仮ディレクトリに画像を保存
if($this->Session->read("image1") != null){
//仮画像保存
$tmpData = $this->MyImageControlle->imageSaveTmp($this->Session->read("image1"),$tmpPath);
//リネームされた画像名とパスを改めてセッションに登録
$this->Session->write("image1",$tmpData);
//「OKFILE.」の意味はココを参照
$this->Image->validationErrors["image1"][0]
="OKFILE.File Is Selected (ファイルは選択されています)";
}
if($this->Session->read("image2") != null){
//仮画像保存
$tmpData = $this->MyImageControlle->imageSaveTmp($this->Session->read("image2"),$tmpPath);
$this->Session->write("image2",$tmpData);
$this->Image->validationErrors["image2"][0]
="OKFILE.File Is Selected (ファイルは選択されています)";
}
if($this->Session->read("image3") != null){
//仮画像保存
$tmpData = $this->MyImageControlle->imageSaveTmp($this->Session->read("image3"),$tmpPath);
$this->Session->write("image3",$tmpData);
$this->Image->validationErrors["image3"][0]
="OKFILE.File Is Selected (ファイルは選択されています)";
}
//エラーなので入力画面へ遷移
$this->render('image_index');
return;
}
//バリデートを経由していない場合は、まだ仮ディレクトリに画像が保存されていない
// (保存さらた画像名は必ず20文字となる)
if(!empty($this->request->data["Image"]["image1"]["tmp_name"]) and strlen(
$this->request->data["Image"]["image1"]["tmp_name"]) != 20){
//仮画像保存
//独自コンポーネントにて処理
$tmpData = $this->MyImageControlle->imageSaveTmp($this->request->data["Image"]["image1"],$tmpPath);
$this->request->data["Image"]["image1"] = $tmpData;
$this->Session->write("image1",$tmpData);
}
if(!empty($this->request->data["Image"]["image2"]["tmp_name"]) and strlen(
$this->request->data["Image"]["image2"]["tmp_name"]) != 20){
//仮画像保存
$tmpData = $this->MyImageControlle->imageSaveTmp($this->request->data["Image"]["image2"],$tmpPath);
$this->request->data["Image"]["image2"] = $tmpData;
$this->Session->write("image2",$tmpData);
}
if(!empty($this->request->data["Image"]["image3"]["tmp_name"]) and strlen(
$this->request->data["Image"]["image3"]["tmp_name"]) != 20){
//仮画像保存
$tmpData = $this->MyImageControlle->imageSaveTmp($this->request->data["Image"]["image3"],$tmpPath);
$this->request->data["Image"]["image3"] = $tmpData;
$this->Session->write("image3",$tmpData);
}
$this->set("user",$user["username"]);
}
/**************************************************************************
* 確認画面
***************************************************************************/
function image_complate(){
//トークンチェック
if(empty($this->request->data["Image"]["token"])
or $this->request->data["Image"]["token"] != $this->Session->read("token")){
$this->redirect(array("controller"=>"mysamples","action"=>"image_index"));
}
$this->set("token",$this->Session->read("token"));
//仮の画像と本画像保管場所
$user = $this->Auth->user();
$tmpPath = "/home/hoge/www/cake2612/img/tmp_image/".$user["username"]."/";
$savePath = "/home/hoge/www/cake2612/img/save_image/".$user["username"]."/";
/*****************************************
* 削除処理(削除ボタンが押下された)
******************************************/
if(isset($this->request->data["image1"])
or isset($this->request->data["image2"]) or isset($this->request->data["image3"])){
//画像1の削除ボタンが押下された
if(isset($this->request->data["image1"])){
$tmpData = $this->Session->read("image1");
//仮画像削除
$this->MyImageControlle->imageDeleteTmp($tmpData["name"],$tmpPath);
$this->Session->delete("image1");
}
if(isset($this->request->data["image2"])){
$tmpData = $this->Session->read("image2");
//仮画像削除
$this->MyImageControlle->imageDeleteTmp($tmpData["name"],$tmpPath);
$this->Session->delete("image2");
}
if(isset($this->request->data["image3"])){
$tmpData = $this->Session->read("image3");
//仮画像削除
$this->MyImageControlle->imageDeleteTmp($tmpData["name"],$tmpPath);
$this->Session->delete("image3");
}
//セッションに画像があるかチェック
if($this->Session->read("image1") != null){
$this->request->data["Image"]["image1"] = $this->Session->read("image1");
}
if($this->Session->read("image2") != null){
$this->request->data["Image"]["image2"] = $this->Session->read("image2");
}
if($this->Session->read("image3") != null){
$this->request->data["Image"]["image3"] = $this->Session->read("image3");
}
//全ての画像がなくなった場合は「image_index」に戻る
if($this->Session->read("image1") == null and $this->Session->read("image2") == null
and $this->Session->read("image3") == null){
$this->render("image_index");
return;
}
$this->set("user",$user["username"]);
$this->render("image_confirm");
return;
}
/*****************************************
* 戻る(戻るボタンが押下された)
******************************************/
if(isset($this->request->data["back"])){
//セッションに画像があるかチェック
if($this->Session->read("image1") != null){
$this->Image->validationErrors["image1"][0]
="OKFILE.File Is Selected (ファイルは選択されています)";
}
if($this->Session->read("image2") != null){
$this->Image->validationErrors["image2"][0]
="OKFILE.File Is Selected (ファイルは選択されています)";
}
if($this->Session->read("image3") != null){
$this->Image->validationErrors["image3"][0]
="OKFILE.File Is Selected (ファイルは選択されています)";
}
$this->render("image_index");
return;
}
/*****************************************
* 保存(保存ボタンが押下された)
******************************************/
$this->Session->delete("token");
if(isset($this->request->data["save"])){
//true なら保存
$savaFls = true;
if($this->Session->read("image1") != null and $savaFls == true){
$tmpData = $this->Session->read("image1");
$this->Session->delete("image1");
//画像本登録
//そのまま画像移動
//$savaFls = $this->MyImageControlle->imageMoveTmp($tmpPath,$savePath,$tmpData["name"]);
//横幅を加工して移動
$savaFls = $this->MyImageControlle->
imageMoveTmpAndWidthChenge($tmpPath,$savePath,$tmpData["name"],200);
$this->request->data["Image"]["image1"] = $tmpData["name"];
}
if($this->Session->read("image2") != null and $savaFls == true){
$tmpData = $this->Session->read("image2");
$this->Session->delete("image2");
//画像本登録
$savaFls = $this->MyImageControlle->
imageMoveTmpAndWidthChenge($tmpPath,$savePath,$tmpData["name"],200);
if(empty($this->request->data["Image"]["image1"])){
$this->request->data["Image"]["image1"] = $tmpData["name"];
}else{
$this->request->data["Image"]["image2"] = $tmpData["name"];
}
}
if($this->Session->read("image3") != null and $savaFls == true){
$tmpData = $this->Session->read("image3");
$this->Session->delete("image3");
//画像本登録
$savaFls = $this->MyImageControlle->
imageMoveTmpAndWidthChenge($tmpPath,$savePath,$tmpData["name"],200);
if(empty($this->request->data["Image"]["image1"])){
$this->request->data["Image"]["image1"] = $tmpData["name"];
}else if(empty($this->request->data["Image"]["image2"])){
$this->request->data["Image"]["image2"] = $tmpData["name"];
}else{
$this->request->data["Image"]["image3"] = $tmpData["name"];
}
}
//1つでも画像の処理に失敗したらDB保存はしない。
if(!$savaFls){
$this->Session->setFlash(
"システム処理に失敗しました。 <br />恐れ入りますが最初から操作し直してください。"
,"default",array("class"=>"alert alert-danger"));
$this->redirect(array("controller"=>"mysamples","action"=>"image_index"));
}else{
//DB保存
//トランザクションを利用している
$this->Image->begin();
$this->Image->create();
if($this->Image->save($this->request->data,false)){
$this->Image->commit();
$this->redirect(array("controller"=>"mysamples","action"=>"image_thankyou"));
}else{
$this->Image->rollback();
$this->Session->setFlash(
"システム処理に失敗しました。 <br />恐れ入りますが最初から操作し直してください。"
,"default",array("class"=>"alert alert-danger"));
$this->redirect(array("controller"=>"mysamples","action"=>"image_index"));
}
}
}
}
function image_thankyou(){
}
}
?>
[ Component ]
<?php
class MyImageControlleComponent extends Component {
public function initialize(Controller $controller) {
$this->controller = $controller;
}
/*****************************************************************************
* 仮ディレクトリへ画像を保存する
*
* $data array $this->request->data[Model名][項目名]
* $path String 保存 Path 例(/hoge/foo/bar/)
*
* 戻り値 array $this->request->data[Model名][項目名]の内容
* ["name"] 新たなファイル名(拡張子あり)
* ["tmp_name"] 新たなファイル名込みのフルPath
******************************************************************************/
function imageSaveTmp($data = array(),$path = null){
//パラメータチェック
if(!isset($path)){
$error = "[Component=MyImageControlleComponent->imageSaveTmp]の第2引数 $path は必須です。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
if(empty($data["tmp_name"])){
$error = "[Component=MyImageControlleComponent->imageSaveTmp]の第1引数 $data は必須です。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
//仮画像保存先ディレクトリ作成(存在すれば作らない)
$dir = new Folder($path,true);
//画像情報格納
list($width, $height, $type, $attr) = getimagesize($data["tmp_name"]);
if($type == 1){$type = ".gif";}elseif($type == 2){$type = ".jpg";}else{$type = ".png";}
if(strlen($data["name"]) != 20){
//ファイル名をランダムに決める
$time = microtime();
$image = substr($time,11).substr($time,2,6).$type;
}else{
$image = $data["name"];
}
//仮画像保存
$file = new File($data["tmp_name"]);
//選択されている画像が変更になった
if($data["tmp_name"] != $path.$image){
if(!$file->copy($path.$image,true)){
$error = "[Component=MyImageControlleComponent->imageSaveTmp]で、ファイルの保存に失敗しました。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
}
$data["name"] = $image;
$data["tmp_name"] = $path.$image;
return $data;
}
/*****************************************************************************
* 仮ディレクトリの画像を削除する
*
* $name String ファイル名(拡張子あり)
* $path String 保存 Path 例(/hoge/foo/bar/)
*
* 戻り値 bool true 削除成功
******************************************************************************/
function imageDeleteTmp($name = null,$path = null){
//パラメータチェック
if(empty($name) or empty($path)){
$error = "[Component=MyImageControlleComponent->
imageDeleteTmp]の第1引数 $name と 第1引数 $path は必須です。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
$file = new File($path.$name);
if($file->delete()){
return true;
}else{
return false;
}
}
/*****************************************************************************
* 仮ディレクトリの画像を移動する
*
* $Path1 String 仮ディレクトリのパス(/hoge/foo/bar/)
* $Path2 String 本ディレクトリのパス(/hoge/foo/bar/)
* $name String ファイル名(拡張子あり)
*
* 戻り値 bool true 削除成功
******************************************************************************/
function imageMoveTmp($Path1 = null,$Path2 = null,$name = null){
//パラメータチェック
if(empty($Path1) or empty($Path2) or empty($name)){
$error = "[Component=MyImageControlleComponent->
imageDeleteTmp]の第1引数 $Path1 と 第2引数 $Path2 と第3引数 $name は必須です。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
//本画像保存先ディレクトリ作成(存在すれば作らない)
$dir = new Folder($Path2,true);
$file = new File($Path1.$name);
if($file->copy($Path2.$name,true)){
$file->delete();
return true;
}else{
return false;
}
}
/*****************************************************************************
* 仮ディレクトリの画像を移動し、画像サイズを変更する
*
* $Path1 String 仮ディレクトリのパス(/hoge/foo/bar/)
* $Path2 String 本ディレクトリのパス(/hoge/foo/bar/)
* $name String ファイル名(拡張子あり)
* $tmpWid Integer 画像の横幅
*
* 戻り値 bool true 削除成功
******************************************************************************/
function imageMoveTmpAndWidthChenge($Path1 = null,$Path2 = null,$name = null,$tmpWid = 100){
//パラメータチェック
if(empty($Path1) or empty($Path2) or empty($name)){
$error = "[Component=MyImageControlleComponent->
imageDeleteTmp]の第1引数 $Path1 と 第2引数 $Path2 と第3引数 $name は必須です。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
//$type『gif -> 1 , jpg -> 2 , png -> 3』
list($width, $height, $type, $attr) = getimagesize($Path1.$name);
if($width > $tmpWid){
if($type == "1"){
$image = ImageCreateFromGIF($Path1.$name); //GIFファイルを読み込む
}elseif($type == "2"){
$image = ImageCreateFromJPEG($Path1.$name); //JPEGファイルを読み込む
}else{
$image = ImageCreateFromPNG($Path1.$name); //PNGファイルを読み込む
}
//サイズ設定
$new_width = $tmpWid;
//圧縮比
$rate = $new_width / $width;
$new_height = $rate * $height;
// 空の画像を作成する
$new_image = ImageCreateTrueColor($new_width, $new_height);
// 画像を普通にリサイズコピーする場合
//ImageCopyResized($new_image,$image,0,0,0,0,$new_width,$new_height,$width,$height);
// サンプリングしなおす場合
ImageCopyResampled($new_image,$image,0,0,0,0,$new_width,$new_height,$width,$height);
// ファイルに保存
$flg = true;
if($type == "1"){
//環境によっては使えない
$flg = ImageGIF($new_image, $Path2.$name);
}elseif($type == "2"){
//3つ目の引数はクオリティー(0~100)
$flg = ImageJPEG($new_image, $Path2.$name, 70);
}else{
$flg = ImagePNG($new_image, $Path2.$name);
}
//メモリを解放する。
//画像を、メモリ上から解放
imagedestroy ($image);
//画像を、メモリ上から解放
imagedestroy ($new_image);
//仮画像削除
$this->deleteImage($Path1,$name);
return $flg;
}else{
//そのまま画像を保存
//画像の加工はないので、「imageMoveTmp」メソッドに渡す
return $this->imageMoveTmp($Path1,$Path2,$name);
}
}
/*****************************************************************************
* 画像を削除する
*
* $Path String ディレクトリのパス(/hoge/foo/bar/)
* $name String ファイル名(拡張子あり)
*
******************************************************************************/
function deleteImage($Path = null,$name = null){
//パラメータチェック
if(empty($Path) or empty($name)){
$error = "[Component=MyImageControlleComponent->
deleteImage]の第1引数 $Path と 第2引数$name は必須です。";
$this->log($error, "error");
echo "error...Look Error Log.";exit;
}
$file = new File($Path.$name);
$file->delete();
}
}
?>
[ Model ]
<?php
App::uses('AppModel', 'Model');
class Image extends AppModel {
public $name = 'Image';
public $actsAs = array();
public $validate=array(
"comment"=>array(
"notEmpty"=>array("rule"=>"notEmpty","message"=>"コメントは必須項目です"),
),
"image1"=>array(
"imageCheck"=>array("rule"=>array("imageCheck")),
),
"image2"=>array(
"imageCheck"=>array("rule"=>array("imageCheck")),
),
"image3"=>array(
"groupNotEmpty"=>array("rule"=>array("groupNotEmpty")),
"imageCheck"=>array("rule"=>array("imageCheck")),
),
);
//[image1][image2][image3]の内どれか1つ選択する必要がある
function groupNotEmpty($data){
//選択Check
if(empty($this->data["Image"]["image1"]["name"]) and empty(
$this->data["Image"]["image2"]["name"]) and empty($this->data["Image"]["image3"]["name"])){
$this->invalidate("image1","画像は最低1つ選択してください");
return true;
}
return true;
}
//画像の内容をチェックする
function imageCheck($data){
$name = current(array_keys($data));
$data = current($data);
//選択されていなければチェックはしない
if(empty($data["name"])){return true;}
//typeチェック
$type = exif_imagetype($data["tmp_name"]);
switch($type){
case IMAGETYPE_GIF:
break;
case IMAGETYPE_JPEG:
break;
case IMAGETYPE_PNG:
break;
default:
$this->invalidate($name,"選択できるのは画像([gif][png][jpag])のみです");
return true;
}
//画像サイズチェック
if($data["size"] > 1024000){
$this->invalidate($name,"登録できる画像サイズは 1M 未満です");
return true;
}
return true;
}
}
?>
[ View ] image_index.ctp
<?php echo $this->Session->flash(); ?>
<?php echo $this->Form->create("Image",array(
'url' => '/mysamples/image_confirm',"novalidate" => true,"class"=>"form-horizontal"
,"style"=>"margin-left:50px","autocomplete"=>"off","enctype"=>"multipart/form-data")); ?>
<?php echo $this->BootstrapCss->input(
"comment",array("type"=>"text","label"=>"コメント","style"=>"width:400px;","height"=>"100px"
,"placeholder"=>"Free Comment...","bs_type"=>"col1","class"=>"form-control"
,"v_error"=>@$this->Form->validationErrors["Image"]["comment"][0])); ?>
<?php echo $this->BootstrapCss->input("image1",array("type"=>"file","label"=>"画像1"
,"style"=>"width:400px;","height"=>"70px","bs_type"=>"col1","class"=>"form-control"
,"v_error"=>@$this->Form->validationErrors["Image"]["image1"][0])); ?>
<?php echo $this->BootstrapCss->input("image2",array("type"=>"file","label"=>"画像2"
,"style"=>"width:400px;","height"=>"70px","bs_type"=>"col1","class"=>"form-control"
,"v_error"=>@$this->Form->validationErrors["Image"]["image2"][0])); ?>
<?php echo $this->BootstrapCss->input("image3",array("type"=>"file","label"=>"画像3"
,"style"=>"width:400px;","height"=>"70px","bs_type"=>"col1","class"=>"form-control"
,"v_error"=>@$this->Form->validationErrors["Image"]["image3"][0])); ?>
<?php echo $this->Form->input("token",array("type"=>"hidden","value"=>$token)); ?>
<?php echo $this->BootstrapCss->button(
"確認",array("bs_type"=>"col1"),array("btn btn-success","glyphicon glyphicon-ok-circle")); ?>
<?php echo $this->Form->end(); ?>
[ View ] image_confirm.ctp
<?php echo $this->Form->create(
"Image",array('url' => '/mysamples/image_complate',"class"=>"form-horizontal")); ?>
<div class="container">
<table class="table">
<thead>
<tr>
<th>Comment</th>
<td><?php echo $this->data["Image"]["comment"] ?></td>
<td>...</td>
</tr>
</thead>
<tbody>
<tr>
<td>画像1</td>
<td><?php if(!empty($this->data["Image"]["image1"]["name"])){
echo $this->Html->image(
"/img/tmp_image/".$user."/".$this->data["Image"]["image1"]["name"]);} ?></td>
<td style="vertical-align: middle;"><?php if(!empty($this->data["Image"]["image1"]["name"])){
echo $this->BootstrapCss->button("削除",array("name"=>"image1","bs_type"=>"col1","div"=>false)
,array("btn btn-danger","glyphicon glyphicon-trash"));} ?></td>
</tr>
<tr>
<td>画像2</td>
<td><?php if(!empty($this->data["Image"]["image2"]["name"])){
echo $this->Html->image(
"/img/tmp_image/".$user."/".$this->data["Image"]["image2"]["name"]);} ?></td>
<td style="vertical-align: middle;"><?php if(!empty($this->data["Image"]["image2"]["name"])){
echo $this->BootstrapCss->button("削除",array("name"=>"image2","bs_type"=>"col1","div"=>false)
,array("btn btn-danger","glyphicon glyphicon-trash"));} ?></td>
</tr>
<tr>
<td>画像3</td>
<td><?php if(!empty($this->data["Image"]["image3"]["name"])){
echo $this->Html->image(
"/img/tmp_image/".$user."/".$this->data["Image"]["image3"]["name"]);} ?></td>
<td style="vertical-align: middle;"><?php if(!empty($this->data["Image"]["image3"]["name"])){
echo $this->BootstrapCss->button("削除",array("name"=>"image3","bs_type"=>"col1","div"=>false)
,array("btn btn-danger","glyphicon glyphicon-trash"));} ?></td>
</tr>
</tbody>
</table>
</div>
<div style="margin-left:100px">
<?php echo $this->BootstrapCss->button(
"戻る",array("name"=>"back","bs_type"=>"col1","div"=>false,"separator"=>" ")
,array("btn btn-warning","glyphicon glyphicon-hand-left")); ?>
<?php echo $this->BootstrapCss->button(
"登録",array("name"=>"save","bs_type"=>"col1","div"=>false)
,array("btn btn-success","glyphicon glyphicon-pencil")); ?>
</div>
<?php echo $this->Form->input("token",array("type"=>"hidden","value"=>$token)); ?>
<?php echo $this->Form->input("comment",array("type"=>"hidden")); ?>
<?php echo $this->Form->end(); ?>
[ View ] image_thankyou.ctp
Thank You...
登録しました。。。