BEAR.Sundayでコンタクトフォームを作ってみる①
BEAR.Sundayでの「Hello World!」①がGoogle検索「BEAR.Sunday Hello World」で1位をゲットしました!
ということで、そろそろBEAR.SundayのHello Worldにも飽きてきたと思いますので、先に進みたいと思います。
次のお題はコンタクトフォームです。
BEAR.Sundayのインストール
bear/skeletonを使ってインストールします。最新の開発版をインストールするためにdev-develop
を指定します。
$ composer create-project bear/skeleton:dev-develop Kenjis.Contact
$ cd Kenjis.Contact
$ composer install
依存パッケージの更新と追加
bear/packageをdevelopブランチに、ray/diをmasterブランチに、そして、メール送信のためにSwiftMailerを追加します。
--- a/composer.json
+++ b/composer.json
@@ -3,7 +3,9 @@
"description":"n/a",
"license": "proprietary",
"require": {
- "bear/package": "~0.11"
+ "bear/package": "dev-develop",
+ "ray/di": "dev-master",
+ "swiftmailer/swiftmailer": "@stable"
},
"require-dev": {
"bear/dev-package": "~0.1@dev"
$ composer update
SwiftMailerを使う準備
SwiftMailerクラスの作成
そのままSwiftMailerを使うこともできますが、ここでは、より簡単に使えるように、Twigと合わせてテンプレートを使えるようにしたSwiftMailerクラスを作成しておきます。
src/Service/SwiftMailer.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\Service;
class SwiftMailer
{
private $mailer;
private $twig;
private $subject;
private $from;
private $to;
private $template;
private $templateVars;
public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig)
{
$this->mailer = $mailer;
$this->twig = $twig;
// logger for debug
// $logger = new \Swift_Plugins_Loggers_EchoLogger();
// $this->mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($logger));
}
/**
* @return \Swift_Message
*/
private function build()
{
$body = $this->twig->render($this->template, $this->templateVars);
$message = \Swift_Message::newInstance()
->setSubject($this->subject)
->setFrom($this->from)
->setTo($this->to)
->setBody($body);
return $message;
}
/**
* @param string $template template filename
* @param array $vars variables to pass template
*/
public function setTemplate($template, array $vars)
{
$this->template = $template;
$this->templateVars = $vars;
return $this;
}
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
public function setFrom($address, $name)
{
$this->from = [$address => $name];
return $this;
}
public function setTo($address, $name)
{
$this->to = [$address => $name];
return $this;
}
/**
* Send mail
*
* @return int the number of recipients who were accepted for delivery
*/
public function send()
{
$message = $this->build();
return $this->mailer->send($message);
}
/**
* Get this message as a complete string
*
* @return string
*/
public function __toString()
{
return $this->build()->toString();
}
}
SwiftMailerFactoryクラスの作成
上のSwiftMailerクラスを生成するファクトリも作成しておきます。
src/Service/SwiftMailerFactory.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\Service;
use Ray\Di\Di\Inject;
use Ray\Di\Di\Named;
class SwiftMailerFactory
{
/**
* @var string
*/
private $context;
private $twig;
/**
* @Inject
* @Named("context=app_context")
*/
public function __construct($context)
{
$this->context = $context;
}
/**
* @Inject
*/
public function setTwig(\Twig_Environment $twig)
{
$this->twig = $twig;
}
/**
* @return \Swift_Mailer
*/
public function create()
{
if ($this->context === 'test') {
$transport = \Swift_NullTransport::newInstance();
} else {
$transport = \Swift_SmtpTransport::newInstance('smtp.gmail.com', '465', 'ssl')
->setUsername($_ENV['MAILER_GMAIL_ID'])
->setPassword($_ENV['MAILER_GMAIL_PASSWORD']);
}
$mailer = \Swift_Mailer::newInstance($transport);
return new SwiftMailer($mailer, $this->twig);
}
}
コンストラクタインジェクション(@Inject
)で名前付きバインディング(@Named
)を使い、$context
にBEAR.Sundayのapp_context
(アプリケーションコンテキスト、いわゆる環境。デフォルトではprod、dev、test、apiのいずれか)を注入しています。
setTwig()メソッドでは、セッターインジェクション(@Inject
)を使い、$twig
にTwig_Environmentインスタンスを注入しています。
create()メソッドではコンテキストにより、SwiftMailerのトランスポートオブジェクトを変更しています。test環境ではSwift_NullTransportを使いメールの転送を行いません。test環境以外ではGmailをSMTPサーバに利用します。
メール用のテンプレートの作成
作成したSwiftMailerクラスで使うメール用のテンプレートを作成します。
var/lib/twig/template/mailer/contact_form.twig
{% autoescape false %}
名前: {{ name }}
電子メール: {{ email }}
コメント:
{{ comment }}
{% endautoescape %}
サーバ起動スクリプトの作成
GmailをSMTPサーバとして利用するにはGmailアカウントの情報が必要です。
ここでは、以下のシェルスクリプトを作成し、環境変数でGmailアカウントの情報をWebサーバに渡すようにします。
server.sh
#!/bin/sh
export MAILER_GMAIL_ID=アカウント@gmail.com
export MAILER_GMAIL_PASSWORD=パスワード
# clear BEAR.Sunday's cache
php bin/clear.php
vendor/bin/bear.server --port=8000 --context=dev .
#php -S 0.0.0.0:8000 -t var/www/ bootstrap/contexts/dev.php
メール送信のテスト
SwiftMailerを使う準備ができましたので、メール送信をテストしてみます。
とりあえず、ページリソースContactを作成し、GETされた場合にメールを送信してみます。
src/Resource/Page/Contact.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\Page;
use BEAR\Resource\ResourceObject;
use Ray\Di\Di\Inject;
use Kenjis\Contact\Service\SwiftMailerFactory;
class Contact extends ResourceObject
{
/**
* @Inject
*/
public function __construct(SwiftMailerFactory $mailer)
{
$this->mailer = $mailer;
}
public function onGet()
{
$data = [
'name' => 'BEAR.Sunday',
'email' => 'bear@example.jp',
'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 (string) $result;
}
}
デバッグのために$mailer
をechoしてメッセージの文字列を表示しています。
また、SwiftMailerのsend()メソッドは処理したメールの数(整数)を返しますので、それを文字列にキャストして返して表示します。
サーバ起動スクリプトを実行し、PHPのビルトインサーバを起動します。
$ sh server.sh
これで、http://0.0.0.0:8000/contact にブラウザからアクセスすると、Gmail経由でメールが送信されるはずです。
うまくいかない場合は、SwiftMailerクラスのコンストラクタの最後にあるEchoLoggerプラグインを登録するコードを有効にすると、SMTPサーバとのやりとりのログがechoされるようになります。
src/Service/SwiftMailer.php
public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig)
{
$this->mailer = $mailer;
$this->twig = $twig;
// logger for debug
// $logger = new \Swift_Plugins_Loggers_EchoLogger();
// $this->mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($logger));
}
というわけで、メール送信だけで終わってしまいましたが、今日はここまでにします。
BEAR.Sundayでコンタクトフォームを作ってみる②へ続く。
関連
Date: 2014/08/11