Aura

Aura:FilterとFormでValidation

by codechord. 0 Comments

ちょっとしたAjax系のFormの実装をする必要があって、
一枚ペラっと作ってもイイんだけど、せっかくだし今風に作ってみようと思い、Auraに手を出した。

Formのためだけに、Wordpress使うのもなんだし、LaravelやSymfony使うのもFatすぎるかなって感じていて。
Auraはフルスタックのフレームワークではなく、必要なComponentをとっつけて組み立てるという感じ。

理解の仕方は、次の順
日本語ドキュメントがあるので、ざっくりはわかる。
・一つ一つのComponentが軽量でソースを追っかけるのも比較的簡単。
・同様に、それぞれがのReadmeドキュメントが整ってる印象。

https://github.com/auraphp
https://github.com/friendsofaura
今回サンプルとして、htmlのフォームでPOSTした内容をバリデーションチェック加えて、json形式で何らか返すというものを
以下の2パターンで作った。それぞれは同じ結果を返す。

・A: Filterをaura/filterを直接使う。(github)
・B: aura/input/Formの継承クラスを作成し、Form内でfilterを行う。(github)

基本

/vendor/auraの中身で、重要そうなのは、web-kernelあたりのよう。
ここでrouter、dispatcher、あとwebコンポーネントにある、RequestとResponseとかが、定義される感じ。

アプリケーションは、/config/Common.phpにかいていく。なお、/config/_env.phpにて、環境の設定を変更をすることで、

  • /config/Dev.php
  • /config/Prod.php
  • /config/Test.php

と、環境別に動作を切り替えれることが出来る。/config/Common.phpは、_env.phpの設定にかかわらず全てにおいて実行される。

DI

関連するサービスをsetし、必要時に、getして使う。

1$di->set(<サービス名>,$di->lazyNew());
2$service = $di->get(<サービス名>);

ルーティングとディスパッチャ

$router->add()でルーティングを指定して、$dispatcher->setObject()のクロージャで、ルーティングの処理をする。

1$router->add(, );
2$dispatcher->setObject(, function () use ($di) {
3  // ここに処理
4});

バリデーションチェック

Aura/Filterを追加する必要がある。Aura/inputも。必要に応じてAura/htmlも追加。

  • HTMLテンプレート書くなら、次のバンドルをcomposerに追加する。
    composer require foa/html-view-bundle
  • フォーム書くなら、次のバンドルをcomposerに追加する。
    composer require foa/filter-input-bundle

さて、説明がうまく出来ないので、以下のA、Bの場合とで、サンプルソースを見比べて欲しい。
/form.htmlの静的フォームから/sendにPOST送信され、フィルタのかけ、Jsonを返すのだが、Bの場合だけDIを使った形となっている。

A:Filterだけの場合
https://github.com/tomothumb/Sample-Aula-validation/blob/5e8dd23b450140ab4f2fe55ac7a0b399dc2bedb3/config/Common.php
Dispacharの中に書いていく。

B: Fromを利用する場合
https://github.com/tomothumb/Sample-Aula-validation/blob/master/config/Common.php
/src/App/From/Contact.phpを追加し、Formの要素とバリデーションの内容を記述する。

違いをGistに書いた。(わかりにくい。。。)

<?php
namespace App\Form;
use Aura\Input\Form;
class Contact extends Form
{
public function init()
{
$this->setField('first_name', 'text')
->setAttribs(array(
'id' => 'first_name',
'size' => 20,
'maxlength' => 20,
));
$this->setField('message', 'text')
->setAttribs(array(
'id' => 'message',
'size' => 200,
'maxlength' => 200,
));
$filter = $this->getFilter();
$filter->addSoftRule('first_name', $filter::IS, 'string');
$filter->addSoftRule('first_name', $filter::IS, 'strlenBetween', 6, 12);
}
}
$di->set('MYAPP/contactform',$di->lazyNew('App\Form\Contact'));
....
$dispatcher->setObject('send', function () use ($di) {
$request = $di->get('aura/web-kernel:request');
$input = $request->post->get();
$response = $di->get('aura/web-kernel:response');
$response->content->setType('application/json');
$response_content = array();
$form = $di->get('MYAPP/contactform');
$form->fill($input);
$success = $form->filter();
if ($success) {
$response_content["message"] = "User input is valid.";
} else {
foreach ($form->getMessages() as $name => $messages) {
foreach ($messages as $message) {
$response_content["message"][] = "Input '{$name}': {$message}";
}
}
}
$response_content["data"] = $input;
$response->content->set($response_content);
$json = json_encode($response->content->get());
$response->content->set($json);
});
$dispatcher->setObject('send', function () use ($di) {
$request = $di->get('aura/web-kernel:request');
$input = $request->post->get();
$response = $di->get('aura/web-kernel:response');
$response->content->setType('application/json');
$response_content = array();
$filter_factory = new FilterFactory();
$filter = $filter_factory->newInstance();
$filter->addSoftRule('first_name', $filter::IS, 'string');
$filter->addSoftRule('first_name', $filter::IS, 'strlenBetween', 6, 12);
$success = $filter->values($input);
if ( $success) {
$response_content["message"] = "User input is valid.";
}else{
$response_content["message"][] = "User input is not valid.";
$messages = $filter->getMessages();
$response_content["message"] = $messages;
}
$response_content["data"] = $input;
$response->content->set($response_content);
$json = json_encode($response->content->get());
$response->content->set($json);
});

設計方法学ぼうとおもってたのに、いつのまにか、アプリケーションの書き方/使い方を学んでいる自分がいる。。。

同じことをSilexとSlimでも今度やってみよう。