BEAR.Sundayでコンタクトフォームを作ってみる⑤
BEAR.Sundayでコンタクトフォームを作ってみる④の続きです。
今までMVCで言うところの「コントローラ」に対応する「ページリソース」しか使ってなかったので、今日は「モデル」に対応する「アプリケーションリソース」も使ってみます。
なお、言うまでもないことですが、BEAR.SundayはそもそもMVCパターンではないフレームワークなので、「コントローラ」と「ページリソース」や「モデル」と「アプリケーションリソース」が全く同じものということではありません。
それでは、フォームに関する処理はアプリケーションリソースに移動します。
アプリケーションリソースの作成
アプリケーションリソースContact\Formを作成し、フォームの処理とメール送信のロジックを移動します。
src/Resource/App/Contact/Form.php
<?php
/**
* Kenjis.Contact
*
* @author Kenji Suzuki <https://github.com/kenjis>
* @license MIT License
* @copyright 2014 Kenji Suzuki
* @link https://github.com/kenjis/Kenjis.Contact
*/
namespace Kenjis\Contact\Resource\App\Contact;
use BEAR\Resource\ResourceObject;
use BEAR\Resource\Code;
use Kenjis\Contact\Service\SwiftMailerFactory;
use Ray\Di\Di\Inject;
class Form extends ResourceObject
{
private $mailer;
/**
* @Inject
*/
public function __construct(SwiftMailerFactory $mailer)
{
$this->mailer = $mailer;
}
/**
* @BEAR\Sunday\Annotation\Form
*/
public function onGet()
{
return $this;
}
/**
* @BEAR\Sunday\Annotation\Form
*/
public function onPost($name, $email, $comment)
{
$this->sendmail($name, $email, $comment);
$this['code'] = $this->code = Code::CREATED;
$this['name'] = $name;
$this['email'] = $email;
$this['comment'] = $comment;
return $this;
}
private function sendmail($name, $email, $comment)
{
$data = [
'name' => $name,
'email' => $email,
'comment' => $comment,
];
$mailer = $this->mailer->create();
$mailer->setSubject('コンタクトフォーム')
->setFrom($data['email'], $data['name'])
->setTo('admin@example.org', '管理者')
->setTemplate('mailer/contact_form.twig', $data);
// echo '<pre>'
// . htmlspecialchars($mailer, ENT_QUOTES, 'UTF-8')
// . '</pre>';
$result = $mailer->send();
return $result;
}
}
対応するテンプレートも作成します。ページリソースのものをほぼそのまま移動するだけです。
src/Resource/App/Contact/Form.twig
<div id="contact_form">
<h1>Contact Form</h1>
{% if code == 201 %}
<p>
Name: {{ name }}<br>
Email: {{ email }}<br>
Comment: {{ comment }}
</p>
<p>Thank you!</p>
{% else %}
<form role="form" action="" method="post" enctype="multipart/form-data">
{{ form(form['__csrf_token']['hint']) }}
<div class="form-group{%if form['name']['error'] %} has-error{% endif %}">
<label class="control-label" for="name">Name</label>
{{ form(form['name']['hint']) }}
<label class="control-label" for="name">{{ form['name']['error'] }}</label>
</div>
<div class="form-group{%if form['email']['error'] %} has-error{% endif %}">
<label class="control-label" for="email">Email</label>
{{ form(form['email']['hint']) }}
<label class="control-label" for="email">{{ form['email']['error'] }}</label>
</div>
<div class="form-group{%if form['comment']['error'] %} has-error{% endif %}">
<label class="control-label" for="comment">Comment</label>
{{ form(form['comment']['hint']) }}
<label class="control-label" for="comment">{{ form['comment']['error'] }}</label>
</div>
<input class="btn btn-default" type="submit" name="submit" value="Send">
</form>
{% endif %}
</div><!-- end of id="contact_form" -->
ページリソースの変更
アプリケーションリソースに移動したロジックを削除し、ページリソースからアプリケーションリソースを呼び出すように変更します。
--- a/src/Resource/Page/Contact.php
+++ b/src/Resource/Page/Contact.php
@@ -11,62 +11,30 @@
namespace Kenjis\Contact\Resource\Page;
use BEAR\Resource\ResourceObject;
-use Ray\Di\Di\Inject;
-use Kenjis\Contact\Service\SwiftMailerFactory;
-use BEAR\Resource\Code;
+use BEAR\Sunday\Inject\ResourceInject;
class Contact extends ResourceObject
{
- /**
- * @Inject
- */
- public function __construct(SwiftMailerFactory $mailer)
- {
- $this->mailer = $mailer;
- }
+ use ResourceInject;
- /**
- * @BEAR\Sunday\Annotation\Form
- */
public function onGet()
{
+ $this['contact_form'] = $this->resource->get
+ ->uri('app://self/contact/form')
+ ->eager->request();
+
return $this;
}
- /**
- * @BEAR\Sunday\Annotation\Form
- */
public function onPost($name, $email, $comment)
{
- $this->sendmail($name, $email, $comment);
+ $this['contact_form'] = $this->resource->post
+ ->uri('app://self/contact/form')
+ ->withQuery(['name' => $name, 'email' => $email, 'comment' => $comment])
+ ->eager->request();
- $this['code'] = $this->code = Code::CREATED;
- $this['name'] = $name;
- $this['email'] = $email;
- $this['comment'] = $comment;
+ $this->code = $this['contact_form']->code;
return $this;
}
-
- private function sendmail($name, $email, $comment)
- {
- $data = [
- 'name' => $name,
- 'email' => $email,
- 'comment' => $comment,
- ];
-
- $mailer = $this->mailer->create();
- $mailer->setSubject('コンタクトフォーム')
- ->setFrom($data['email'], $data['name'])
- ->setTo('admin@example.org', '管理者')
- ->setTemplate('mailer/contact_form.twig', $data);
-
-// echo '<pre>'
-// . htmlspecialchars($mailer, ENT_QUOTES, 'UTF-8')
-// . '</pre>';
-
- $result = $mailer->send();
- return $result;
- }
}
onGet()メソッドでは、以下のようにしてアプリケーションリソースContact\FormをGETでリクエストしています。
$this['contact_form'] = $this->resource->get
->uri('app://self/contact/form')
->eager->request();
テンプレートも変更します。
--- a/src/Resource/Page/Contact.twig
+++ b/src/Resource/Page/Contact.twig
@@ -8,41 +8,7 @@
</head>
<body>
<div class="container">
- <h1>Contact Form</h1>
-
-{% if code == 201 %}
- <p>
- Name: {{ name }}<br>
- Email: {{ email }}<br>
- Comment: {{ comment }}
- </p>
- <p>Thank you!</p>
-{% else %}
- <form role="form" action="" method="post" enctype="multipart/form-data">
- {{ form(form['__csrf_token']['hint']) }}
-
- <div class="form-group{%if form['name']['error'] %} has-error{% endif %}">
- <label class="control-label" for="name">Name</label>
- {{ form(form['name']['hint']) }}
- <label class="control-label" for="name">{{ form['name']['error'] }}</label>
- </div>
-
- <div class="form-group{%if form['email']['error'] %} has-error{% endif %}">
- <label class="control-label" for="email">Email</label>
- {{ form(form['email']['hint']) }}
- <label class="control-label" for="email">{{ form['email']['error'] }}</label>
- </div>
-
- <div class="form-group{%if form['comment']['error'] %} has-error{% endif %}">
- <label class="control-label" for="comment">Comment</label>
- {{ form(form['comment']['hint']) }}
- <label class="control-label" for="comment">{{ form['comment']['error'] }}</label>
- </div>
-
- <input class="btn btn-default" type="submit" name="submit" value="Send">
- </form>
-{% endif %}
-
+ {{ contact_form|raw }}
</div>
</body>
</html>
フォーム部分は、変数contact_form
にセットされていますので、以下のように変更します。contact_form
はHTMLなので|raw
を付けてエスケープされないようにします。
{{ contact_form|raw }}
インターセプターの設定の変更
フォームを処理するクラスが変わりましたので、インターセプターをバインドするクラスも変更する必要があります。
--- a/src/Module/AppModule.php
+++ b/src/Module/AppModule.php
@@ -42,7 +42,7 @@ class AppModule extends AbstractModule
// aspect @Form annotaion
$this->bindInterceptor(
- $this->matcher->subclassesOf('Kenjis\Contact\Resource\Page\Contact'),
+ $this->matcher->subclassesOf('Kenjis\Contact\Resource\App\Contact\Form'),
$this->matcher->annotatedWith('BEAR\Sunday\Annotation\Form'),
[$this->requestInjection('Kenjis\Contact\Interceptor\Contact\Form')]
);
これで、フォームがアプリケーションリソースになりました。
ブラウザから http://0.0.0.0:8000/contact にアクセスしてみます。
▼コンタクトフォーム
フォームのまわりに枠ができ、その左上に「app://self/contact/form」と表示されています。この部分がアプリケーションリソースであることがわかります。
何も入力せずに[Send]ボタンを押すと、検証エラーが表示されます。
▼検証エラー
なお、このデフォルトで表示されるリソース名とアイコン(haloと呼ばれています)が邪魔でページが見づらく消したい場合があります。そのような場合は、URLに?halo=0
を付けてアクセスするとオフになります(再度有効にしたい場合は?halo=1
)。
▼haloをオフに
かなり完成してきました。今日はここまでにします。
BEAR.Sundayでコンタクトフォームを作ってみる⑥へ続く。
過去記事
- BEAR.Sundayでコンタクトフォームを作ってみる① BEAR.SundayのインストールとSwiftMailerによるメール送信
- BEAR.Sundayでコンタクトフォームを作ってみる② フォームの作成
- BEAR.Sundayでコンタクトフォームを作ってみる③ Twigのautoescapeと文字化けの修正
- BEAR.Sundayでコンタクトフォームを作ってみる④ Aura Formの利用とAOP
- BEAR.Sundayでコンタクトフォームを作ってみる⑤ アプリケーションリソースの利用 ←今ここ
関連
Date: 2014/08/15