Technote

by sizuhiko

PHPカンファレンス関西に参加してきました

<!– more –>4/2に開催されたPHPカンファレンス関西に参加してきました。

実行委員の皆様お疲れさまでした。ものすごい楽しいイベントでした。

僕はLTでBehatの話をしたのですが、他のプレゼンテーションがとてもバラエティにとんでいて、とても勉強になったし、交流もできて良かったです。

プログラムの内容や、それぞれの内容は他の参加者の方が詳しく書いていたりするので、簡単にKPT形式で振り返っておきます。

※アンケート書いたけど、やっぱり落ち着いたところで考えると違いますね。

KEEP

  1. 前日入りは楽
  2. 会場がキレイ(税金がふんだんに投入されている感のある・・・以降自粛)
  3. 関西での大規模イベント(東京からの参加でしたが。。。)
  4. スムーズな進行、時間通りに進んでいて感動した
  5. 懇親会LTも大スクリーンで見やすい
  6. 懇親会の食事が美味しい
  7. ドラ娘がかわいい

Problem

  1. 電源が少ない。自分はAirだし、Wifiルータも10時間持つURoad-9000だったので大丈夫でしたが、全体的に困っていた人が多かった印象
  2. 欲を言えば2トラックぐらいあると良かったかも(もっとコード的な欲望がある人向けセッションみたいな)
  3. 16Fのレストランはテンパっていた w (本編に関係ないですが)
  4. 懇親会同一会場は待ち時間が微妙
  5. (本編LTで)ドラ娘の仕事が少なかった(懇親会では大変そうでした。お疲れさまでした)
  6. LT発表者が東方面だった

Try

  1. 次はハッカソン? (ザワっ
  2. 青年団も何か告知できるようにしておきたかった (謎
  3. また来年もあれば参加したい

で、スライドなんですが、いつものslideshareにアップしてたんですが、何度やっても失敗するようになったので、おさらばすることにしました(過去のファイルはそのまま置いておきますが)。取り急ぎ、MyOperaのストレージに置いたので、こちらをダウンロードして見てください。

また、懇親会のジャンケン大会で本をもらいました。

最後に、東京に帰る新幹線で、WiMAXルータURoad-9000がどのくらい使えるか検証してみました。

  1. トンネル以外は概ね問題なく接続でき、とても快適
  2. トンネル以外での不調エリアは、米原、浜名湖近辺だけ
  3. 上記いずれも体感です(ご了承ください)

ということで、N700系であればWifi使えるけど、それ以外どうする?といった場合、WiMAXも十分行けますよ、あなた。(宣伝)

Behatのインストールについての注意事項

<!– more –>4/2 に行われるPHPカンファレンス関西にて、BehatについてLTをすることになりました。

そこで最近Behatをダウンロードしてみたのですが、git submoduleでのSymfonyコンポーネントのインストールで問題がありますので、解決策を書いておきます。

  1. Behat 本体のインストール

    git clone git://github.com/Behat/Behat.git

  2. サブモジュールのインストール

    cd Behat git submodule update –init

とくに問題がなければ、しばらくして終了しますが、本稿執筆次点では以下のようなエラーで中断してしまいます。

Initialized empty Git repository in /Behat/vendor/Symfony/Component/Translation/.git/
remote: Counting objects: 220, done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 220 (delta 147), reused 141 (delta 94)
Receiving objects: 100% (220/220), 52.61 KiB, done.
Resolving deltas: 100% (147/147), done.
fatal: reference is not a tree: d5cdaba8550b7b99f37d2aad345dd8ebbe3efb9c
Unable to checkout 'd5cdaba8550b7b99f37d2aad345dd8ebbe3efb9c' in submodule path 'vendor/Symfony/Component/Translation'

そこで、エラーになったサブモジュールの変更ログを確認します。

git log --oneline -p -- vendor/Symfony/Component/Translation

上記コマンドを実行すると、以下のように表示されます。

85d8dac updated vendors
diff --git a/vendor/Symfony/Component/Translation b/vendor/Symfony/Component/Translation
index f70e0ba..d5cdaba 160000
--- a/vendor/Symfony/Component/Translation
+++ b/vendor/Symfony/Component/Translation
@@ -1 +1 @@
-Subproject commit f70e0ba1b04e7db4b3aa6d122470291d4fb34732
+Subproject commit d5cdaba8550b7b99f37d2aad345dd8ebbe3efb9c
da2503a updated submodules
diff --git a/vendor/Symfony/Component/Translation b/vendor/Symfony/Component/Translation
new file mode 160000
index 0000000..f70e0ba
--- /dev/null
+++ b/vendor/Symfony/Component/Translation
@@ -0,0 +1 @@
+Subproject commit f70e0ba1b04e7db4b3aa6d122470291d4fb34732

ここで表示されたログの1行目「85d8dac updated vendors」の85d8dacを使ってチェックアウトします。

git checkout 85d8dac~ -- vendor/Symfony/Component/Translation
git submodule update

こうすることで、サブモジュールのインストールが継続できます。

  1. 実行する

    bash-3.2$ ./bin/behat.php ……………………………………………………………. ……………………………………………………………. ……………………………………………………………………….

    36 scenarios (36 passed) 222 steps (222 passed) 0m7.045s

成功したら、インストールは完了です。

PHPのBDDフレームワーク Behat について発表してきました

第55回PHP勉強会@関東で発表してきました

2011/2/10にPHP勉強会が約半年ぶりに開催されました。以前、発表するぜーと公言していたので、今回は万全を期してと思いきや最近の多忙に負けそうになりました。が、前日(というか当日朝4時)までバタバタしながら準備してました。。。

今回は昨年のPHP祭りで日本語ハックしたBehatの入門編です。あのときはLTという形であまり詳細に触れられなかったので、30分という時間ですが実際に1からやってみました。 ここでは実際に「やってみよう」で実践した手順について解説します。

はじめに

スライドの「1. インストール」でも書いていますが、まずBehat本体をインストールしてください。私がforkした日本語対応版をcloneすると「3. 日本語環境」の部分をスキップできます。 「2. テスト環境」に関しては、今回behat_webstepsを流用しました。それ以外にもGoutte-for-Behat(https://github.com/ThePixelDeveloper/Goutte-for-Behat)というものもあります。どちらもHTMLクライアントのエンジンとして「Goutte」を使っています。前者はgoutte.pharが含まれていますが、後者は含まれていないので別途Goutteをcloneする必要があります。ただ後者の方がstepsのコードは流用しやすいかもしれません。

準備しよう

まず初期状態のディレクトリを以下のようにしました。

|-- Behat Behat本体のclone
|-- behat_websteps behat_webstepsのclone

練習環境を作る

behat_webstepsを土台にして、テスト環境を作ります。といっても、まずは単にコピーするだけです。

cp -R behat_websteps sandbox

フィーチャーファイルを作成する

スライドでも引用したgihyo.jpでのcucumberについてとてもわかりやすい連載「第22回 Railsアプリの受け入れテストをCucumberで書こう」のフィーチャーを使用します。

vi sandbox/features/sample.feature

実際のコードは以下のとおりです。

# language: ja
フィーチャ: ユーザを管理したい

  シナリオ: ユーザの登録
    前提 "ユーザ登録"ページを表示している
    もし "email"に"example@example.com"と入力する
    かつ "name"に"赤松 祐希"と入力する
    かつ "age"に"22"と入力する
    かつ "Create"ボタンをクリックする
    ならば "User was successfully created."と表示されていること
    かつ "example@example.com"と表示されていること
    かつ "赤松 祐希"と表示されていること
    かつ "22"と表示されていること

ここでcucumberと違うのは1行目(フェーチャの前)に言語指定をするところです。現時点のBehatではこれを書く事でja.xmlを利用してくれます。

実行してみる

フィーチャーはbin/behatコマンドでテストします。

bash-3.2$ Behat/bin/behat sandbox/features/sample.feature 

画面には、以下のように出力されます。

<code>
フィーチャ: ユーザを管理したい

  シナリオ: ユーザの登録                                     # features/sample.feature:4

<span style="color: goldenrod">
    前提 "ユーザ登録"ページを表示している
    もし "email"に"example@example.com"と入力する
    かつ "name"に"赤松 祐希"と入力する
    かつ "age"に"22"と入力する
    かつ "Create"ボタンをクリックする
    ならば "User was successfully created."と表示されていること
    かつ "example@example.com"と表示されていること
    かつ "赤松 祐希"と表示されていること
    かつ "22"と表示されていること
</span>
1 scenario (<span style="color: goldenrod">1 undefined</span>)
9 steps (<span style="color: goldenrod">9 undefined</span>)
0.123s
<span style="color: goldenrod">
You can implement step definitions for undefined steps with these snippets:

$steps->前提('/^"([^"]*)"ページを表示している$/', function($world, $arg1) {
    throw new EverzetBehatExceptionPending();
});

$steps->もし('/^"([^"]*)"に"([^"]*)"と入力する$/', function($world, $arg1, $arg2) {
    throw new EverzetBehatExceptionPending();
});

$steps->かつ('/^"([^"]*)"ボタンをクリックする$/', function($world, $arg1) {
    throw new EverzetBehatExceptionPending();
});

$steps->ならば('/^"([^"]*)"と表示されていること$/', function($world, $arg1) {
    throw new EverzetBehatExceptionPending();
});
</span>
</code>

ステップ(テストの定義)が記述されていないので、9つの未定義エラーが表示されています。その下にはスケルトンが表示されているので、まずこれをコピペしてstepファイルを作成します。

ステップファイルの作成

stepファイル「webteststep.php」に前節のスケルトンを貼付けます。以下のようになるでしょう。

<?php

$steps->前提('/^"([^"]*)"ページを表示している$/', function($world, $arg1) {
    throw new EverzetBehatExceptionPending();
});

$steps->もし('/^"([^"]*)"に"([^"]*)"と入力する$/', function($world, $arg1, $arg2) {
    throw new EverzetBehatExceptionPending();
});

$steps->かつ('/^"([^"]*)"ボタンをクリックする$/', function($world, $arg1) {
    throw new EverzetBehatExceptionPending();
});

$steps->ならば('/^"([^"]*)"と表示されていること$/', function($world, $arg1) {
    throw new EverzetBehatExceptionPending();
});

また実行してみましょう。

<code>
bash-3.2$ Behat/bin/behat sandbox/features/sample.feature 
フィーチャ: ユーザを管理したい

  シナリオ: ユーザの登録                                     # features/sample.feature:4

<span style="color: goldenrod">
    前提 "ユーザ登録"ページを表示している                           # features/steps/web_test_step.php:5
      TODO: write pending definition
</span><span style="color: skyblue">
    もし "email"に"example@example.com"と入力する          # features/steps/web_test_step.php:9
    ...(** 省略 **)
</span>

1 scenario (<span style="color: goldenrod">1 pending</span>)
9 steps (<span style="color: skyblue">8 skipped</span>, <span style="color: goldenrod">1 pending</span>)
0.089s
</code>

未定義(undefined)から、ペンディングに変わりましたね。これは貼付けたコードが現時点でPending例外を投げているためです。

ステップを記述する

ステップの中身はbehat_webstepsのcommon.phpを流用しました。

<?php

$steps->前提('/^"([^"]*)"ページを表示している$/', function($world, $page) {
  $page = $world->__getPath($page);

  $world->client->request('GET', $page);
  $world->__getClientProperties();
});

$steps->もし('/^"([^"]*)"に"([^"]*)"と入力する$/', function($world, $field, $value) {
  assertNotNull($world->page,"No webpage loaded");
  $form = $world->__getForm('Create');
  $form[$field]->setValue($value);
});

$steps->かつ('/^"([^"]*)"ボタンをクリックする$/', function($world, $button) {
  assertNotNull($world->page,"No webpage loaded");
  $form = $world->__getForm('Create');
  $world->client->submit($form);
  $world->__getClientProperties();
});

$steps->ならば('/^"([^"]*)"と表示されていること$/', function($world, $text) {
  assertNotNull($world->page,"No webpage loaded");
  assertContains($text,$world->output);
});

実行してみましょう。

<code>
bash-3.2$ Behat/bin/behat sandbox/features/sample.feature 
フィーチャ: ユーザを管理したい

  シナリオ: ユーザの登録                                     # features/sample.feature:4

<span style="color: firebrick">    前提 "ユーザ登録"ページを表示している                           # features/steps/web_test_step.php:8
      Unknown path 'ユーザ登録'. You can define it in [features_folder]/support/paths.php
      Failed asserting that an array has the key <string:ユーザ登録>.
</span><span style="color: skyblue">    もし "email"に"example@example.com"と入力する          # features/steps/web_test_step.php:14
    ...(** 省略 **)
</span>

1 scenario (<span style="color: firebrick">1 failed</span>)
9 steps (<span style="color: skyblue">8 skipped</span>), <span style="color: firebrick">1 failed</span>)
0.355s
</code>

すると「ユーザ登録」なんてURLは見つからないというエラーになります。まぁそうですね。URLに関しては画面名と実際のhttpリクエストするURLを関連づけておく必要があります。これはgoutte以外のHTTPクライアントを使っても同じことです。ベースとしたbehat_webstepsではsupport/paths.phpにそのマッピングを書くようにしていますので、追加します。

<?php
$world->paths = array();
$world->paths['ユーザ登録'] = "http://localhost/user_regist.php";

テストを失敗させる

ここまでで、初期段階の準備は完了です。ではまたテストを実行してみましょう。

<code>
bash-3.2$ Behat/bin/behat sandbox/features/sample.feature 
フィーチャ: ユーザを管理したい

  シナリオ: ユーザの登録                                     # features/sample.feature:4

    <span style="color: green">前提 "ユーザ登録"ページを表示している                           # features/steps/web_test_step.php:8</span>
    <span style="color: firebrick">もし "email"に"example@example.com"と入力する          # features/steps/web_test_step.php:14
      The current node list is empty.</span>
    <span style="color: skyblue">...(** 省略 **)</span>

1 scenario (<span style="color: firebrick">1 failed</span>)
9 steps (<span style="color: green">1 passed</span>, <span style="color: skyblue">7 skipped</span>, <span style="color: firebrick">1 failed</span>)
0.114s
</code>

テストを実行してみると、最初に入力フォームに値をセットしようとするところで失敗します。まだユーザ登録画面を表示するプログラムはありません。

それでは実際に動作するコードを書いてみましょう。

実装する

ここではあくまでテストを通過させる簡単なコードを書いてみます。画面の入力フォームから入力された値を表示するuser_regist.phpを書いてみましょう。

<!DOCTYPE html>
<html>
    <head>
      <title>ユーザ登録</title>
    </head>
    <body>
        <div><?
            if ($_POST["submit"]) {
                echo "User was successfully created.". "<br />";
                echo "name = "     . $_POST['name']  . "<br />";
                echo "e-mail = "   . $_POST['email'] . "<br />";
                echo "age = "      . $_POST['age']   . "<br />";
            }
        ?></div>
        <form method="post" action="user_regist.php">
            <div>
                <label>名前:</label><input type="text" name="name" value="">
            </div>
            <div>
                <label>e-mail:</label><input type="text" name="email" value="">
            </div>
            <div>
                <label>年齢:</label><input type="text" name="age" value="">
            </div>
            <div>
                <input type="submit" name="submit" value="Create">
            </div>
        </form>
    </body>
</html>

※まぁなんとも安直なコードですが、ご勘弁を・・・

作成したファイルをドキュメントルートに設置してテストを実行しましょう。

<code>
bash-3.2$ Behat/bin/behat sandbox/features/sample.feature 
フィーチャ: ユーザを管理したい

  シナリオ: ユーザの登録                                     # features/sample.feature:4

<span style="color: green">    前提 "ユーザ登録"ページを表示している                           # features/steps/web_test_step.php:8
    もし "email"に"example@example.com"と入力する          # features/steps/web_test_step.php:14
    かつ "name"に"赤松 祐希"と入力する                         # features/steps/web_test_step.php:14
    かつ "age"に"22"と入力する                             # features/steps/web_test_step.php:14
    かつ "Create"ボタンをクリックする                          # features/steps/web_test_step.php:21
    ならば "User was successfully created."と表示されていること # features/steps/web_test_step.php:26
    かつ "example@example.com"と表示されていること             # features/steps/web_test_step.php:26
    かつ "赤松 祐希"と表示されていること                           # features/steps/web_test_step.php:26
    かつ "22"と表示されていること                              # features/steps/web_test_step.php:26
</span>
1 scenario (<span style="color: green">1 passed</span>)
9 steps (<span style="color: green">9 passed</span>)
0.389s
</code>

やったー、グリーンでテスト成功です。

さいごに

今回はbehatwebstepsをベースにしましたが、HTTPクライアントは何でも大丈夫です。今回goutteでしたが、BehatはPHPUnitを使うのでPHPUnitのPHPUnitExtensions_SeleniumTestCaseを使うのも1つでしょう。Javascriptが使われているサイトなどでは、こちらの選択になりますね。

大事なことはアジャイルでドキュメントを書く事と、無駄なドキュメントでなく実行可能なドキュメントである、ということですね。プレーンテキストなのでプログラマじゃなくても、お客さんでも読めるし、書いてもらう事も可能かもしれません。打ち合わせでフィーチャファイルを議事録的に書きながら進めることもできると思います。

今後の展開としては、一般的なwebstepに関してはgoutteを使った日本語版を、私のgithubアカウントで公開予定です。4/2のPHPカンファレンス関西までには公開して何かしゃべりたいなーと思っていますが、ちょっとテーマと違うか。。LT狙いで何か。。

Behat RC1も期待して待ちましょう!!

懇親会でも話題になったのですが、PHPSpecはどこへ行ってしまったのか・・・

それと、pharファイルが使えないよ!という方(当日朝3時までのオレ)、はこちらの「Pharは便利だけど --enalbe-zend-multibyteが有効だと文字化けしてしまう」を参考にしてください!!

バリデーションプラグインと組み合わせて使うと便利な、確認画面を出すjQueryプラグイン

<!– more –>これまで確認画面を出すだけのものや、入力チェックだけをするものはプラグインとして出ていたのですが、どうも組み合わせて使おうとすると不便なことが多かったので、プラグインを自作してみました。

ダウンロード:

ソースコードは以下のgithubで公開しています。

https://github.com/sizuhiko/confirmForm

デモ:

まずどのような動作をするのか、デモページで確認したほうがわかりやすいと思います。以下のURLから操作してみてください。

/demo/confirmForm/demo/index.html

デモサイトでは入力チェックにex-valudationプラグインを使っています。

必須条件:

特徴:

  • 確認画面を出すかどうかは自分で判断します
  • 確認画面でOKが選択されるまでフォームはSubmitされません
  • 一般的なフォームの形式であれば、ほとんどカスタマイズ(オプションで指定する)の必要なし

一般的なフォームって?

このプラグインでは以下のような構造のHTMLフォームが利用されることを想定しています。

<form action="posted.html" method="get" id="inputForm">
  <div>
    <label for="user_id">ID:</label>
    <input type="text" name="id" id="user_id" value=""><span class="required">*</span>
  </div>
  <div>
    <label for="user_name">Name:</label>
    <input type="text" name="name" id="user_name" value=""><span class="required">*</span>
  </div>
  <div>
    <label for="user_sex">Sex:</label>
    <fieldset id="user_sex">
      <input type="radio" name="sex" id="user_sex_male" value="1"><label for="user_sex_male">Male</label>
      <input type="radio" name="sex" id="user_sex_female" value="2"><label for="user_sex_female">Female</label>
      <span class="required">*</span>
    </fieldset>
  </div>
  <div>
    <label for="user_lang">Language:</label>
    <select name="lang" id="user_lang">
      <option value="">-- please select --</option><option value="jp">Japanese</option><option value="en">English</option>
    </select><span class="required">*</span>
  </div>
  <div>
    <label for="user_receive_news">Receive News Mail:</label>
    <fieldset id="user_receive_news">
      <input type="checkbox" name="news" id="user_reveive_news_sports" value="1"><label for="user_receive_news_sports">Sports</label>
      <input type="checkbox" name="news" id="user_reveive_news_music" value="2"><label for="user_receive_news_music">Music</label>
      <input type="checkbox" name="news" id="user_reveive_news_computer" value="3"><label for="user_receive_news_computer">Computer</label>
    </fieldset>
  </div>
  <div class="buttons">
    <input type="submit" value="next" id="submit_ok">
  </div>
</form>

これはデモページのフォーム部分そのものなのですが、項目をdivタグで囲い、その中の項目名はlabelで入力フィールドはinputやselectを使うようなデザインです。

プラグインで必要になる記述

javascriptファイルをロードします。 jqModelプラグインを使っているので、jqModal、もちろんjqueryもロードしてください。

<script charset="utf-8" type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.js"></script>
<script charset="utf-8" type="text/javascript" src="http://dev.iceburg.net/jquery/jqModal/jqModal.js"></script>
<script src="../src/confirmform.js"></script>

jqModalのスタイルシートが必要になります。また、jqModalのexampleで記述されているConfirmサンプルのスタイル定義を利用しているので、サンプルHTML上から切り出したスタイルシートをvendorディレクトリに用意しました。これを使うと簡単に利用を開始することができます。

<link charset="utf-8" href="../vendor/jqModal/jqmConfirm.css" type="text/css" rel="stylesheet"></link>
<link charset="utf-8" href="http://dev.iceburg.net/jquery/jqModal/jqModal.css" type="text/css" rel="stylesheet"></link>

プラグインの初期化

プラグインを利用するためには、HTML上に1つ確認画面用の空エレメントを追加する必要があります。場所はbody内であればどこでもかまいません。

<div id="confirmForm"></div>

idの値も特に意味はありません。ここではconfirmFormという値にしておきます。

プラグインのインスタンスを初期化するには、$(“入力フォームのセレクタ”).confirmForm(“確認画面用のセレクタ”, オプション) を使います。

$(document).ready(function(){
  ...
  $("#inputForm").confirmForm("#confirmForm", {});
  ...
}

ひとまず、このようにシンプルな宣言で動作します。実際に利用する場面では、入力フォームでselectボックスやcheckbox,radioボタンなどを利用していると思います。デフォルトの挙動では値をinputのvalueから取り出して表示するだけなので、コード値を名前に変換する必要があるかもしれません。このあたりのカスタマイズは、オプション節で解説します。

確認画面を表示する

このプラグインでは確認画面は自分で表示する必要があります。たとえばバリデーションプラグインの成功時コールバックで呼び出すようなイメージです。

$("#inputForm").confirmShow();

これはとてもシンプルで、confirmShow関数を呼び出すだけです。

OKが押されたかどうかチェックする

このプラグインでは、確認画面でOKが選択されたらもう一度入力フォームでSubmitを実行します。そのため入力チェックが再実行されて、コールバックが呼び出されるかもしれません。そのためにOKが既に選択されていたらそのままreturnするような実装にすることになると思います。

validCallback:function() {
  if($("#inputForm").isConfirmed()) {
    return;
  }
  $("#inputForm").confirmShow();
}

確認済みかどうかはisConfirmed関数を呼び出すだけです。入力内容が問題ないときのコールバックがvalidCallbackだったとすると、上記のような実装になります。

オプション

実際に利用する場面では、必ずしもinputのvalue値が確認画面に出れば良い訳ではありません。また、タイトルを変更したりボタンのラベルを変更したりもしたいでしょう。そのためにプラグイン初期化時にオプションを指定できるようにしてあります。

オプション一覧:

名前意味デフォルト値概要

title タイトル Are you sure? 確認画面上部に表示されるタイトルを文字列で指定

yes はいボタンのラベル Yes 文字列で指定

no いいえボタンのラベル no 文字列で指定

findLavel ラベルを探索して文字列を返すためのコールバック 1つ前の要素のtext部分(一般的なフォームのtextボックスではlabelになる) radioやcheckboxのようにラベルがfieldsetの外側にあるようなケースで独自にコールバック関数を実装する

formatValue 値をカスタマイズするためのコールバック inputやselectのvalue値 value値がコードだが、確認画面では値(名前)で出したい場合に独自にコールバック関数を実装する

separator 複数選択値の区切り文字 ,(コンマ) 同一nameがある場合に、値を区切る文字列

ラベル文字列のコールバック

デフォルトの挙動は以下のとおりです。

'findLabel': function(inputField) {
    return $(inputField).prev().html();
}

textボックスは直前の要素がlabelであることを想定しているので、すべてが一般的なフォームのレイアウトで、textボックスしか利用していなければ、オプションの指定は必要ありません。しかし実際はlabelが右だったり1つ親の要素だったりすることがあります。 このような場面ではコールバックを実装してください。

例えばデモページでは以下のようなコードになっています。

'findLabel': function(field) {
    switch(field.name) {
    case 'sex':
        return 'Sex';
    case 'news':
        return 'Receive News Mail';
    default :
        str = $(field).prev().html();
        return str.substring(0, str.length-1);
    }
}

findLabelに関してはformatValurのように項目別ではなく、functionで受け取って独自にカスタマイズする方式を取っています。これは項目名は一括ルールで変換できる場合が想定できるためです。

※このオプションに関しては、将来formatValueのようにhashでも指定できる(併用)方式に変更する予定です。

値をカスタマイズするためのコールバック

inputやselectのvalue値は必ずしも確認表示用には向いていないこともある(例えばコード値になっているなど)ので、このようなケースではコールバック関数を実装してください。

例えばデモページでは以下のようなコードになっています。

'formatValue':{
  'sex':function(field) {
    return {1:"Male", 2:"Female"}[$(field).val()];
  },
  'lang':function(field) {
    return {'jp':"Japanese", 'en':"English"}[$(field).val()];
  },
  'news':function(field) {
    return {1:"Sports", 2:"Music", 3:"Computer"}[$(field).val()];
  }
}

formatValue自体は各入力項目のname属性をキーにしたhashで定義します。

さいごに

今後以下の機能について、バージョンアップを予定しています。

  • yes,noボタンの左右を逆に指定できるようにする
  • selectやcheckbox、radioなどタイプごとに推奨フォームを想定してラベル値を取得する
  • findLabelをhashでもオプション指定できるようにする

その他カスタマイズ要望などあれば、機能追加していきたいな、と思っています。

PHPmatsuri was greatest event for PHP developer.

<!– more –>I went PHPmatsuri on last weekend. PHPmatsuri was great-full Hackathon style event about PHP in Japan. I had prepared about the event as staff.

私は先週末PHP祭りに行ってきました。PHP祭りは、日本のPHP界隈では最大のハッカソン形式のイベントです。私はスタッフとして準備に携わってきました。

In 10/2 morning(8:00 am), staffs meets up hall of the event(Harumi Grand Hotel). We were setting some desks, chairs, electronics line, audios and reception space.

スタッフは10/2の朝8:00に晴海グランドホテルに集合して、会場のセッティングを行います。

I wait participants of the event at front of the hotel, and I showed them to the room. I could look for them easily, because any participants had iPhone and navigated by google-map.

受付が始まる直前にホテルのフロント前に移動し、参加者を会場へ案内します。皆さんiPhoneを片手に地図を見ながら来るので、すぐに参加者とわかりました。

At first, I started ice break for strained participants. And I introduce to them Mr. Hiro Yoshioka, then started first session. The session has be very important for Japanese developer. Should check his blog & slides.

まず最初はアイスブレークから。皆さんの緊張を解きほぐします。会場が暖まったところで、よしおかさんに基調講演をしていただきました。このセッションはPHPに限らずに日本の開発者にとってぜひ聞いて欲しかったセッションとなりました。ぜひよしおかさんのブログをチェックしてください。

The important thing is “English or die” for us. Almost Japanese developer have satisfaction with only Japanese information. Because some Japanese hacker translate English to Japanese with his effort. But Yoshioka san says, “should dispatch some information with English to world-wide”. I know it is very important.So, I wrote this post in English. Some guys same thinks, time line on twitter about phpmatsuri filled with his impressive words.

注目すべきキーワードは“English or Die"でした。日本ではみんな日本語訳のドキュメントを作るのが好きで、著名なブロガーやハッカーがやってくれていますね。でもそうではなくて各自が英語を使って海外に発信していくのが重要だと。僕もそう思うし(だから英語で書いてみた)、よしおかさんの講演中のtwitter TLを見ればみんな共感していたのがわかります。

The second session was Practical PHP5.3 by Mr. Nate Abele. He is developing lithium now. Before, he was CakePHP lead developer. In 9/25, Mr. Rasmus Lerdorf talk about same keywords at PHP-conference. Nate talked about some details more than Rasmus with using sample codes.For example PSR-0, closure…

次のセッションはNateによる実践PHP5.3。1週間前のPHPカンファレンスでRasmusが講演した内容と似ていたけど、より詳細に踏み込んだ感じだった。特にPSR-0とかクロージャとかlithiumの例も交えて解説していました。

Since afternoon, the room was separated to 2 space between conference and Hackathon. On the conference space, talked about CakePHP2.0 by Graham Weldon, Lithium by Nate Abele & Joel Perras and some sponsor’s session. On the Hackathon space, opened workshop about Symfony2, CakePHP and Lithium by the core developer. I presided on conference space, but had very interesting to Hackathos space.

午後からは会場を講演スペースと開発スペースに分割しました。講演スペースでは、コアデベロッパーから各フレームワークのセッションあり、スポンサーセッションあり。開発スペースではコアデベロッパーと一緒にワークショップができたり、各々のテーマで開発したりしていました。僕は司会進行だったので講演スペースに付きっきりでしたが、開発スペースがすごく気になっていました。

After dinner, Mr. Kris Wallsmith talked about Symfony2 at confernce space. Same time, Redbull’s girls came to Hackathon space.

夕食が終わると、KrisによるSymfony2のセッションが開始。ちょうどその頃レッドブルガールがキャンペーンにやってきてくれました。

In that time, I was not able to be heard while preparing next surprise present. I was waiting for 3 cakes. When Symfony2 session ended, the cakes carried into the room. Everybody crowded around cakes and take many photos. So, the nice idea(real cake) was started by Japanese CakePHP community on 2 years ago. In this time, it added Lithium and symfony. The cakes made by Paper Moon. I know the shop is very nice cafe. I recommend for you.

僕はちょうど次のサプライズに向けて準備中でSymfony2のセッションはほとんど聞けませんでした。それは日本のCakePHPイベントでは恒例のリアルケーキです。今回は僕が担当だったのと、とにかくLithiumの出来映えがどうなのか心配だったのです。Symfony2セッションが終わるころホテルの人にケーキが運び入れてもらいました。みんな群がって来て写真を取りまくっていました。ケーキは南麻布のPaper Moonさんにお願いしました。良い店なのでお勧めです。

And sounds of StarWars heard, JIREI master entered. He look like Jedi master! JIREI means the use-case. 2 teams of CakePHP and symfony competed presentation to get a degree of JIREI master. So, @HIROCAST won competition and became JIREI master. He talked about Agile development by symfony.

スターウォーズの曲と共にJIREI masterが入場。ここから事例紹介セッション「JIREI night」が始まります。CakePHPとsymfonyに別れ交互に事例発表を行い、勝ったのは@HIROCASTさんの「アジャイルな開発をチームでやってみた」(symfony)に決定しました。

Time is over 23:00. But everyone continue to develop about themself theme. I started myself theme too. I tried OpenpearPEG for develop parser of Cucumber feature.

事例紹介が終了したのが23時過ぎ。ここからようやく自分の開発時間です。OpenpearPEGでCucumberのパーサーを作ろうと思っていました。

About 2 hours later, I saw some problem. But file of feature don’t match PEG because it isn’t structured. I started giving it up. I was looking for difference theme. So, I got destiny project. It’s Behat. I had feeled very interesting about this project. I decided this to be my theme.

Time is over 5:00. My challenge finished. I go back to my room. What my room-mates was developing his theme in the room !

2時間ぐらい頑張ったのですが、自然言語はPEGと相性が悪いように思い、諦めかけて違うテーマを探していたら、運命の出会いが待っていました。それが「Behat」です。これで行くぞ、と決めたのです。そして5時頃なんとか日本語フィーチャが通るようにハックして部屋に戻りました。合部屋の人はすっかり寝ているのかと思ったら、なんと部屋で開発していました!みんな頑張ってるなー

I got up 7:00 on 10/3. After breakfast, I wrote presentation for demonstration on event room. Everybody get up, but they were maybe very tired. Afternoon 10/3, demonstration about every theme started. The entries are 33. Each presentation is 4 minutes, and the style is Japanese LT having "Dora-Musume”. Whenever demonstration finished , the auditor posts the score from Google-Form.

1時間半ぐらい寝て、7:00から朝食を取りイベント会場でデモ大会用のプレゼンを作成。みんな会場入りするけど、お疲れの様子です。どうも結構な人数が徹夜でやっていたようで。。10/3午後からデモ大会の開始です。発表は1人4分、日本のLT形式(もちろんドラ娘付き)です。なんと33人のエントリーがありました。各プレゼンが終わると事例発表と同じGoogleフォームから投票できるようになっています。そういえばドラ娘の写真がありません。どなたかプリーズ。

My position is 8th in sector-1. But I started on 7th by few accidents. Since sector-2, I presided. All demonstration was finished 3 hour later. The talker and auditor was very tired. long long time LT had been first time for us.

僕は最初の8番目の予定だったのですが、並び順を間違えて7番手でプレゼンとなりました。その後セクター2からは司会にバトンタッチ。全部のLTが終わったのが3時間後(1時間おきに休憩はありましたよ)。こんなに長いLTは初めてで、すごく疲れました。

And……. I won Hacker Prize. It means best performance into these demonstrations. I got new iPod-touch of prize. I’m very happy !

そして運命の結果発表。僕はハッカー賞に選ばれました。これは最高得点の賞なんです。賞品は新しいiPod Touchです!

Long long time was spent, phpmatsuri finished. I think almost participants and staffs were satisfaction. And for Japanese PHP developer, it will become to trigger to publish some information positively. I think so.

At last, thanks for 2 days. @yando and staffs, everybody.

長い時間が過ぎ、PHP祭りは終了しました。参加者/スタッフともに満足できる内容だったと思っています。また日本のPHP開発者にとって積極的に情報発信をするきっかけになるイベントになったんじゃないかと思いました。最後に、2日間ありがとうございました。特に@yandoさん、そしてスタッフ・参加者の皆様に感謝です。