PHP Matsuri以降、実は一度ブログの更新がありましたが、自分の事が書いてあったので照れくさくて翻訳していません。そして立て続けにLithiumの新しいリリースの知らせがありましたので和訳を作成しました。文中に出てくるスタートアップにはセキュリティの権威、Chris ShiflettさんやPHPのUnicode実装に奮戦していたAndrei Zmievskiさんが在籍し、さらにはSean Coatesさんが。またTostyのCTOのMitch Pirtleさんは有名CMS Joomlaの作者です。PHP界のビッグネームがこぞってLithiumを実際に使い始めているというエキサイティングな様子が見て取れます。ではどうぞ。

原文

http://dev.lithify.me/lithium/wiki/blog/Lithium-0-9-9-99-Problems-But-a-Framework-Aint-One

Lithium 0.9.9: 99 Problems But a Framework Ain't One

ワオ、しばらくこのブログを不在にしてました。僕の時間は何処に行ったんだろう?夏の間はしようとしていた事が全て減速していました。僕自身や他のチームメンバーは新しい仕事やスタートアップの立ち上げで多忙でした。我らがプロジェクトマネージャー、GarretSourceForge内でプロダクトリーダーにポジションに就きました。我々もこれをとても嬉しく思います。これについては近いうちにもう少しわかると思います。

また前回触れたようにいくつかのイベントを開催したり、参加してきたのでここ数ヶ月は忙しかったです。なんにせよはっきり言うと長いリリースをしないで時間が過ぎてしまいました。こういった事はもう起こしたくないとはっきり思っています。ええ、本当に済みませんでした。
それはさておき、今日は思いがけないリリース日です。ちょうど二日前にプロジェクト公開の記念日を迎えました。(以前からアナウンスはしていましたがコードとサイトが公開されたのは11月3日でした)また今日はRemember Rememberの日です。(訳注 映画Vフォーバンデッタの台詞 "Remember Remeber The 5th of November" )
また色々な事がありましたが特に前回のリリース以降、将来的には高品質なアプリケーションの為のデファクトフレームワークになる為にがんばってきました。こんな事やこんな事ヤクの毛狩りが無いように。

立ち上げ

この8月にMongoDBを利用したトラフィックの多いプライベートセールEコマースサイト、Tosty.comが開始しました。そしてこのサイトはLithiumで構築されています。Tosty.comのCTOによるこのケーススタディの発表のビデオを見る事もできます。
また個人的に喜ばしい事として今から2週間にBrooklyn Betaというカンファレンスに参加しました。多くの人がこれについて既に記事を書いています。ここでカンファレンスについてはまとめない事にします。このイベントはAnalogFictive Kinのジョイントベンチャーで、彼ら一人一人を個人に敬意を持っています。なのでかれらが立ち上げたいくつかのベータ版のプロダクトMapalongGimme Barにはわくわくしました。しかも彼らは両方ともLithiumを使っているんです!
彼らのフレームワーク上での実践と優れたアプリケーションを見るのはエキサイティングでした。そしてついに完成したわけです。これらのチームからのフィードバックは今のLithiumには不可欠でした。みなさんありがとうございました。

リリースハイライト

今回のリリースは予定したものではありませんでしたが、クオリティをさらに向上させています。約400のコミットが12人の有志によって行われました。これは過去2回のリリースの3倍以上です。また過去4回のリリースの合計に匹敵するくらいの大きさです。

全ての変更を説明しても実用的ではないでしょう。ここに変更のハイライトをリストします。特にコアアーキテクチャとのやり取りに注目してみます。

Filters::apply(): Filters クラスはLithiumでメソッドに対してレイジーにフィルタ処理を行う為の新しい機構です。この新しいメソッドはまだ読み込まれていないスタティックなクラスへフィルタを適用します。例としてPOSTモデルがあり、クエリのログを取る場合はこうなります。:

use app\models\Posts;
use lithium\analysis\Logger;

Posts::applyFilter("find", function($self, $params, $chain) {
Logger::info(json_encode(array("posts" => $params)));
return$chain->next($self, $params, $chain);
});

このフィルタはブートストラップ処理の中で適用されています。よってPOSTクラスはリクエスト中で使われているかどうかに関わらず常にロードされます。このフィルターをレイジーに適用すると以下のようになります。:

use lithium\analysis\Logger;
use lithium\util\collection\Filters;

Filters::apply('app\models\Posts', 'find', function($self, $params, $chain) {
Logger::info(json_encode(array("posts" => $params)));
return$chain->next($self, $params, $chain);
});

このフィルタの効果は1つ上の例と同じです。ですが、Filtersクラスを通しているため、このフィルタはPostクラスが既に読み込まれていない場合はすぐには適用されません。この場合はPostsクラスのFindメソッドが呼びだされるまではフィルタは適用されません。

Object::_instance() と Libraries::instance(): Lithiumは当初からクラス間の依存を定義する際に$_classes属性を使う規約を持っています。これらの依存関係を個別にコンストラクタで上書きする事ができます。
しかしこのインスタンス化のプロセスは少々ぎこちないものでした。クラスの名前を$_classes配列から取得し、 new $class() としていました。現在はObjectとStaticObjectをワンライナーでそれぞれの依存のキーに設定できます。また好きなパラメータも下記のように指定できます。:

class Foo {

protected$_classes = array("renderer" => "app\extensions\template\Custom");

publicfunction render() {
$renderer = $this->_instance("renderer", array("path" => "views/"));
// ...
}
}

Libraries::instance() もよく似た動きをします。クラス型か Libraries::locate()のような名前を受け取り、見つかったクラスを指定されたパラメーターでインスタンス化します。

Request::accepts()によるコンテンツ認証 : Request オブジェクトはコンテンツ認証をサポートしました。認証にはHTTP Acceptedパラメーターを使います。アプリケーションの中で使われるコンテンツのタイプをMedia クラスで設定された設定をもとに返します。.
Model::update() と Model::remove(): Model クラスに2つのメソッドが追加されました。これは複数のドキュメントやレコードを一度に操作できます。
MongoDBスキーマサポート: このリリースではMongoDBのスキーマサポートが改良されました。Mongoオブジェクトを簡単に記録するだけではなく、 $_schema プロパティを使ってLithiumに期待するフィールドの情報を伝えることできます。MongoIDを文字列で渡す事で自動的にMongoIDオブジェクトを生成し問い合わせや更新に使います。
APIドキュメンテーション: その他の機能の為にこのリリースには多くのAPIドキュメントがf組まれます。これらは間もなく docs pageで公開されます。(訳注、反映済���)さらにドキュメントは新しいli3_docsで提供されます。
HTTPメタデータによるルーティング: これまではルーティングはURL内のパターンでのみマッチしていました。現在は全てのRequestオブジェクトのプロパティに拡大されました。これはおなじみのRouter APIで指定します:

// Only allow POST requests to FooController::create():
Router::connect("/create", array("Foo::create", "http:method" => "POST"));

// Allow POST or PUT::
Router::connect("/update", array("Foo::update", "http:method" => array("POST", "PUT")));

// Only match if on the dev server:
Router::connect("/secret", array("Secret::index", "http:host" => "dev.application.com"));

// Only match if request is over HTTPS:
Router::connect("/admin", array("Foo::index", "env:https" => true));

次のリリースのいくつかの変更もハイライトしようと思います。UUIDジェネレーターを再実装したDenis de Bernardy,に感謝します。これにより複雑なコードを明らかに減らす事ができました。これによりパスワードのセキュリティに使われるコアの暗号化を改良できます。また透過的なCSRF対策もフレームワーク上に間もなく実装されます。
さらに彼と何人かの才能ある日本の開発者がそれぞれPostgreSQLのサポートを実装しました。これも次回のリリースでデビューします。
最期に TextMate pluginに小さな改良がありました。アプリケーションで使いテストを実行した後、エラーが発生した場所にTextMate上でジャンプできます。Macユーザなら試してみてください。

API changes

大きなリリースなのでいくつかの後方互換性の無い変更があります。幸いにも小さな変更なので簡単に修正できます。

  • $this->render('foo') の呼び出しはコントローラー内で動かなくなります。代わりにこの呼び出しは$this->render(array('template' => 'foo'))に変更してください。
  • Inflector::camelize() は "_" と "-" を置換します。 (以前は "_" だけを置換していました).
  • データベース設定にカスタムポートを使う場合、 "port" キーはサポートしなくなります。その代わりに "host" キーのフォーマットを "host:port"としてください。
  • Model::_connection() をバックエンドを直接呼び出すのに使っている場合、このメソッドが廃止予定である事に注意してください。かわりに新しい実装である Model::connection()を利用できます。
  • LithiumのG11n機構を使っている場合、CatalogAPIの2つの変更に注意してください。: read() と write() メソッドの最初のパラメータは反映したい設定の名前です。 read() の場合、 true をいつでも指定できます。こうすれば以前の実装と同じです。
  • 簡単に移行する場合は全ての read() の呼び出しをCatalog::read(...) から Catalog::read(true, ...)としてください。
    write() を置き換える場合は動揺ですがやや自動的ではありません。 以前の呼び出しが: Catalog::write('message', 'en', $data, array('name' => 'runtime')), の場合、現在は:Catalog::write('runtime', 'message', 'en', $data)となります。

    What's next?

    このリリースが表に出ると、チームは次のリリースに向けて動く事に興奮しています。僕らはあと2つの大きな機能を安定版のリリース前に実装します。またいくつかの優れたプラグインがリリースの準備ができています。メーリングリストやフォーラムで沢山の質問を受けているのが、Lithiumの全てが集まっている所を探すことの難しさです。ブログやポッドキャスト、ビデオにプレゼンテーションです。僕らはちゃんと聞いています。来週のアナウンスを楽しみにしてください。
    それじゃ、"remember, remember the 5th of November!" (訳注:台詞です。)
    ~ nate ~

    リリースのダウンロード
    全ての変更履歴

    -訳ここまで

    久々のリリースという事で情報量が多く、3時間強も掛かってしまいました。十分に集中していたとは言えないのですが。個人的にはNateの持っている交友関係の広さや彼がPHPのコミュニティでアクティブな様子が伺えます。また彼のポストには洋楽や洋画の引用がよくありますので、理解を深めるにはこういったものも嗜むと良さそうですね。近日中の次のアナウンスを楽しみにしましょう。