Symfony な人たちが「A Year With Symfony – Writing healthy, reusable code」という本を話題にしていたので、
Facebook 上で「楽しそうな本だ」と申し上げたところ、
@ganchiku が、「え、買ったよ」的な反応をしてくれました
せっかくなので買ってみた。(目次を見ずに)

以下、ふんわりこんな感じですよというお話。

I. The journey from request to response
– リクエストからレスポンスへの冒険

Httpリクエストが送られてから、レスポンスを返すまで、どのような流れになっているかを
解説している章。
HttpKernalInterface についてと、どのようにして Controller につないだり
例外をハンドリングするかを知ることができる。

II. Patterns of dependency injection
– Dependency Injection パターン

Service、Parameter の定義の仕方について解説している章

III. Project structure
– プロジェクトの構成

プロジェクトを形作る、それぞれの要素について説明する章
Controller, Form, Domain定義、Event などなど。

IV. Configuration conventions
– 設定のルール

設定ファイルと、メタデータのマッピングについてなど。

V. Security
– セキュリティ

Symfony のセキュリティについてなど。
Session の設定、コントローラーのACL、入力バリデーション、出力エスケーピング

VI. Being a Symfony developer
– Symfony開発者になる

「Symfony 開発者」が心がけることなど。
再利用可能なコードはどうあるべきか。

こんにちは。 先日 6月4日に、Symfony2勉強会が開催されました。

実は、 Symfony2 勉強会への参加はこれが初めてだったりします。
第2部から参加しました。

今、 Symfony2 で Bundle (いつかオープンソース) をつくっておるので、
「あーこうすりゃいいのか」っていうヒントが多く散りばめられていて良かったです。
あと、スタッフのTシャツがオサレですね。

講演のテーマは

  • Symfony2 + Behat(Bundle)でテストファースト開発 @hidenorigoto
  • Symfony2 のフォームについて @fivestr
  • PHPマイクロフレームワーク Silex 入門 @brtriver
  • Symfony2でより良いソフトウェアを作るために @iteman

ということでした。個別にそれぞれ、感想を書くのもいいですが、
FormComponent を復習したかったので、手を動かしてみました。

以下が発表スライド
http://www.slideshare.net/fivestar/symfony2-8203873

この発表の質問の中に、i18n まわりの事が出ていました。
僕も、大いに気になってしまったので、考えてみました。

Symfony2 の i18n は TranslationComponent という、FormComponent と ValidatorComponent
と分かれているように、これまた別のコンポーネントで管理されています。

となると、何か特別な操作が必要なのでは、と疑うわけです。

結論から言うと、 Label や Error は、 メッセージさえ用意しておけば、 symfony1.x と同じように
勝手に翻訳してくれます。嬉しい\(^o^)/

TranslationComponentの設定や、メッセージファイルの形式・置き方は、
http://symfony.com/doc/2.0/book/translation.html
の通りです。

symfony-standard に入っている、 DemoBundle で試してみます。

まず、fallbackを日本語にします。 (ロケールが明示されていないときの設定)

app/config/config_dev.yml

framework:
    router:   { resource: "%kernel.root_dir%/config/routing_dev.yml" }
    profiler: { only_exceptions: false }
    translator: { fallback: ja } # ← 追加

以下のような src/Acme/DemoBundle/Resources/translations/messages.ja.yml を作ります。
(YAMLじゃなくても、symfony1.x でも使われていた、XLIFF 形式も受け付けるよ!
しかし、ネストされたIDを用意できるのは Symfony2の新機能で、YAML (or PHP) 形式だけの強みのようです。
あと、個人的にYAMLが好き。)

Resources/translations/messages.ja.yml

Email: Eメール
Message: メッセージ

http://example.com/app_dev.php/demo/contact にアクセス

見事、日本語になりました。これで、多言語対応への不安が1つ減りましたね。

仕組みもちょっと調べてみました。

Symfony2 では、 Twig をテンプレートエンジンとして利用している場合、 TwigBundle が TranslationComponent
への導線を用意しているようです。
( PhpEngine の場合は、 FrameworkBundle が導線を用意しているようです。)

TwigBundle/Resources/views/Form/div_layout.html.twig の一部

{% block field_label %}
{% spaceless %}
    
{% endspaceless %}
{% endblock field_label %}

のように、しっかり trans filter を使っているのがわかります。

あと、Doctrine2 ORM のドキュメント翻訳やりたいと思ってます。
6/30 に Doctrine 2.1 がリリースされる予定とのことなので、正座して待たずに、
情報を掴んでいきたいところですね。

次回は懇親会とか行きたいお。

Symfony2 で遊んでいます。

で、Doctrine2.0 でモデルを定義するときに少し困ったことが。

以下のようなモデルを想定しました。

User (id, ..)
Cart (user_id, …)

id, user_id はそれぞれ主キーで、 user_id は 外部キーです。
User は Cart を 1つしか持てないという想定で、1対1の関係です。

アノーテーションを使ってモデルを定義すると、

User側

/**
 * @orm:Id
 * @orm:Column (type="integer")
 * @orm:GeneratedValue (strategy="AUTO")
 */
protected $id;

Cart側

/**
 * @orm:Id
 * @orm:OneToOne (targetEntity="User")
 * @orm:JoinColumn (name="id", referencedColumnName="id")
 */
protected $user;

とかなるかなー、っておもって
doctrine:schema:create をやってみたんですが、Cart に主キーがないんだぜ
と怒られてしまいました。

よくよく、ドキュメントを良く読むと衝撃的なあれが。

http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/composite-primary-keys.html

Doctrine 2 supports composite primary keys natively. Composite keys are a very powerful relational database concept and we took good care to make sure Doctrine 2 supports as many of the composite primary key use-cases. For Doctrine 2.0 composite keys of primitive data-types are supported, for Doctrine 2.1 even foreign keys as primary keys are supported.

間違ってるかもしれない、ほんわか翻訳

Doctrine2は最初から複合主キーに対応しています。複合主キーはとても強力なリレーショナルデータベースの概念であり、私たちは念を入れてさまざまなユースケースの複合主キーに対応したいと思います。Doctrine 2.0 ではプリミティブ型の複合主キーに対応され、2.1ではさらに外部キーを主キーとすることにも対応されています。

うほー。ってことは Doctrine2.1 を乗せないと、上のようなモデルを定義することはできないてことかー?