CakePHP3でモデルを使わないでお問い合わせフォームを作りたい
お問い合わせフォームをとにかく作りたかったんです。
でもモデルからDBのテーブルから全部作って…というわけではなく、入力フォームがあってメールで送信できる、というようなお問い合わせフォームにしたかったんです。
でもバリデーションチェックはしたいんです。
上記のような場合、モデルのないフォームがおすすめです。
割とブログ記事も多いのですが、実際に役立ったので自分も書きます。
- 「モデルのないフォーム」
- 必要なのは3つのファイル
- ContactForm.php(フォーム)を作る
- ContactsController.php(コントローラ)を作る
- index.php(ビューテンプレート)を作る
- おまけ
- 終わりに
【自分の環境】
macOS Catalina
PHP7.4.2
CakePHP3.8
MAMP5.7
Apache2.2
MySQL5.7
必要なのは3つのファイル
必要なのは以下の3つのファイルです。
Formディレクトリがなかったら作成しましょう。
/src/Form/ContactForm.php (フォーム)
/src/Controller/ContactsController.php (コントローラ)
/src/Template/Contacts/index.php (ビューテンプレート)
割と手軽ですよね。
ContactForm.php(フォーム)を作る
今回は体裁として名前欄、メール欄、お問い合わせ内容欄の3つを設けます。
それぞれname、email、bodyという値の命名です。
<?php namespace App\Form; use Cake\Form\Form; use Cake\Form\Schema; use Cake\Validation\Validator; use Cake\Mailer\Email; class ContactForm extends Form { // お問い合わせフォームのスキーマを定義する protected function _buildSchema(Schema $schema) { $schema ->addField('name', ['type' => 'string']) ->addField('email', ['type' => 'string']) ->addField('body', ['type' => 'text']); return $schema; } // バリデーション内容を定義する protected function _buildValidator(Validator $validator) { $validator ->notEmpty('name','名前を入力してください。'); $validator ->notEmpty('email','メールアドレスを入力してください。') ->add('email', 'format', [ 'rule' => 'email', 'message' => 'メールアドレスを入力してください。']); $validator ->notEmpty('body','本文を入力してください。'); return $validator; } // バリデーション後に実行したい処理を記述する protected function _execute(array $data) { // メールを送信する処理(今回は省略) return true; } }
ご覧のようにファンクションは3つあります。
スキーマを定義する_buildSchemaファンクション。
バリデーション内容を定義する_buildValidatorファンクション。
バリデーション後に実行したい処理を記述する_executeファンクション。
内容は他のファイルでも見たようなかんじで、あまり難しいことは書いてないので、特に説明はしません。
ContactsController.php(コントローラ)を作る
次にコントローラです。
<?php namespace App\Controller; use App\Form\ContactsForm; class ContactsController extends AppController { public function initialize() { parent::initialize(); $this->loadComponent('Flash'); $this->viewBuilder()->setLayout(false); } public function index() { $contacts = new ContactForm(); if ($this->request->is('post')) { if ($contacts->validate($this->request->getData())) { if ($contacts->execute($this->request->getData())) { $this->Flash->success(__('ご意見・ご要望を送信しました!')); } else { $this->Flash->error(__('送信に失敗しました。')); } }else{ $this->Flash->error(__('送信に失敗しました。')); } } $this->set(compact('contacts')); } }
普通のコントローラと変わりませんが、上の方で以下の記述をしています。
「use App\Form\ContactForm;」
これで先ほどのContactFormを使うよ、と宣言しています。
indexアクションで入力があった時の処理を書いています。
ちなみに自分の場合はどうしてもバリデーションが作動しなかったので、「$contacts->validate($this->request->getData())」と明示的にバリデーションさせています。
本来はその先の「$contacts->execute($this->request->getData())」でバリデーションが動くらしいのですが、自分の場合はvalidate()としていることはお伝えしておきます。
いま少し言いましたが、execute()メソッドではデータが有効な時のふるまいを定義します。
ここではフラッシュを表示させています。
index.php(ビューテンプレート)を作る
最後にビューテンプレートを作ります。
<?php echo $this->Html->css('contacts/index'); ?> <?= $this->Flash->render() ?> <div class="main"> <div class="users form"> <div class="logo"> <?= $this->Html->image('logo.png', [ "alt" => "cake", 'url' => ['controller'=>'pages','action'=>'top'], 'width'=>'230', 'height'=>'100' ]); ?> </div> <?= $this->Form->create($contacts) ?> <fieldset> <legend>ご意見・ご要望フォーム</legend> <?= '<p>名前</p>' ?> <?= $this->Form->text('name',['size'=>30]) ?> <?= $this->Form->error('name'); ?> <?= '<p>メールアドレス</p>' ?> <?= $this->Form->text('email',['size'=>30]) ?> <?= $this->Form->error('email'); ?> <?= '<p>ご意見・ご要望</p>' ?> <?= $this->Form->textarea('body',['rows'=>10,'cols'=>40]) ?> <?= $this->Form->error('body'); ?> <br> <?= $this->Form->button('送信する!') ?> <?= $this->Form->end() ?> </fieldset> </div> </div>
これに関しては、フォームの有無に関わらない内容なので、特に長い説明はしません。
名前欄、メール欄、お問い合わせ内容欄があります。
中盤ですが、「$this->Form->create($contacts)」として、$contactsを入れることを忘れないでください。
これを入れないとバリデーションメッセージが出なかったり、いろいろと困ります。
おまけ
フォームとしては説明は以上です。
ただお問い合わせフォームとして大事なのがメール送信です。
実際にフォームの_executeファンクションで書いていますが、記述は省略しています。
ここに関しては長くなるので、次回、別記事で説明します。
終わりに
以上となります。
モデルなしで手軽にお問い合わせフォームが作れるのは便利ですよね。
実際に動かすともっとわかってくると思います。
ぜひトライしてみてください。
メール送信に関しては次回詳しく説明します。
ありがとうございました。