Hatena::ブログ(Diary)

24時間CakePHP このページをアンテナに追加 RSSフィード

CakePHP1.2.8以前、1.3.5以前に重大なセキュリティホールが見つかりました。
ただちにコアを最新版にアップデートすることをお勧めします。

参考: CakePHPのSecurityComponentに深刻なセキュリティホールが見つかりました - Shin x blog

2011/12/30

CakePHP 1.3.14と2.0.5のリリース(訳)

CakePHPコアチームはCakePHP2.0.5*1と1.3.14*2を素早くリリースできたことを誇りに思います。

2.0.4から合計で、90以上のコミットがあり、40以上の問題が解決されました。変更の完全なリストは変更ログページ*3で見ることができますが、以下に2.0.5で成された変更の簡単なまとめを挙げます:

  • Cacheにおける返り値が正しく直されました。ドキュメントにあるように、falseが常に失敗を指し示します。
  • foreignKeyのないhasOneアソシエーションによる連鎖削除(cascading deletes)が正しく動作するようになりました。
  • SQLiteのために、キャッシュファイルのファイル名に「"」*4を含まないようになりました。
  • テーマのアセットファイルのファイル名が空白文字を含む場合でも、ディスパッチャーを通して正しく配信されるようになりました。
  • ViewTaskで二重に複数形化(pluralization)されることを修正しました。
  • Cacheヘルパーはcallbacksオプションを使用しているときの多くの問題が修正されました
  • TextHelper::excerpt()がドキュメント通りに動作するようになりました。
  • $tablePrefixを使うモデルが遅延読み込みされた時、正しく動作するようになりました。
  • namedパラメータクエリパラメータについてのルーティング問題が解決されました。
  • Shell::$pluginが追加され、より正しいヘルプと使用方法ドキュメントが生成できるようになりました。
  • CakeEmailが同一のメールでインラインと通常の組み合わせの添付ファイルを正しく扱えるようになりました。またインライン添付ファイルも動作するようになりました。

1.3ブランチでは、1.3.13から35以上のコミットがあり、25以上の問題が解決されました。変更の完全なリストは変更ログページ*5で見ることができますが、以下に1.3で成された変更の簡単なまとめを挙げます:

  • 画像のフォーム送信ボタンでアセットタイムスタンプ付けがされるようになりました。
  • Postgresのリテラル値を含むvirtualFieldsが正しく動作するようになりました。
  • ユーザ定義のヘッダはEmailComponent::reset()でリセットされるようになりました
  • CookieComponentで2.0.xアプリケーションで生成されたクッキーを読めるようになりました。
  • PHP5.4との互換性が改善されました。
  • アセットの相対プロトコルURLが正しく動作するようになりました。
  • TextHelper::excerpt()がドキュメント通りに動作するようになりました。

私たちは素晴らしいリリースになるように、2.1ブランチとそのシェイプアップに熱心に仕事をしてきました。

2.1は2.0の完全な後方互換性を持ち、多くの有用な機能を追加しました。

2.1で何が予定されいて、何が完了したかのリストは、ロードマップ*6と、進行中の2.1の移行ガイド*7を見てください。

素晴らしいCakePHPコミュニティに、目覚ましい活躍全てに、今一度の感謝を述べます。

あなたの貢献と愛がなければ、CakePHPはなかったことでしょう。

後書き

Bakeryのリリース記事の訳です。

http://bakery.cakephp.org/articles/markstory/2011/12/29/cakephp_1_3_14_and_2_0_5_released

2.1ブランチでの活発な動向にも目が離せなくなってきました。

前リリースが緊急リリースだったこともあり、長い期間と多めの変更になっていますが、軽微なものが多いのですぐにバージョンアップして良いことでしょう。


それでは皆様、良いお年を:D

2011/12/20

Migrationsプラグインの実践的運用

CakePHP Advent Calendar 2011

CakePHP Advent Calendar 2011 : ATND 20日目の記事です。

19日目:akiyanさんCakePHPの「OrderdBehavior」と「TreeBehavior」はマジで使うべき : akiyan.com

イントロダクション

CakeDCが提供しているMigrationsプラグインは、データベースのインクリメンタルなバージョン管理を行うプラグインで、githubでホストされています。

RoR(Ruby on Rails)のMigrationsをリスペクトしているのは間違いなさそう(どこにも書いてないけど)ですが、中身はそれなりに違います。

Migrationsプラグインの詳細な説明は

CakePHP Migrations plugin: easily version and deploy whole applications by Pierre Martin, Cake Development Corporation

を見てください(英語)。

バージョン管理システムとベストマッチ

CakeDCの記事にもある通り、Migrationsプラグインバージョン管理システムとの協調に大きく貢献します。

これは例えば、開発中はトピックブランチ*1を必ず作って、マージしても良いと判断されたらその大元(masterやdevelopブランチ)へマージする、といった運用がよく行われることと思います。

ここでトピックブランチ内でデータベーススキーマを変更することは度々あることでしょう*2

これを、そのブランチの開発者の開発環境外*3適用するにはどういった方法が考えられるでしょう?

  1. スキーマファイルを用い、cake schema update
  2. SQLダンプを都度適用する
  3. 手動(!)
  4. その他独自の手法

2番目と3番目の方法はあまりにも非効率的で、複数人で開発する時はもはや致命的と言っていいほどの運用でしょう。

スキーマで事足りている、というのならそれもまた是ですが、コールバックにやや不満が残るところです。

独自の方法は情報共有を密にしなければいけない他、学習コストも考えられます。

Migrationsプラグインを使えば、コマンド一発で全てのスキーマバージョンのコントロールが行えるため、スキーマの変更を伴う機能の追加・排除を統一的な手順によって行うことができます。

前提条件

この記事では上記のような、

で行うことを前提に、Migrationsプラグイン運用する実践的なTIPSの紹介をします。

バージョンの生成

バージョンとは、Migrationsプラグインが管理するスキーマ変更点を記述するもので、これをインクリメンタル*4に羅列することによって、アプリケーションスキーマのロードマップが描かれます。

最初のバージョンは、全てのテーブル*5の作成という支持を与えることになります。

手動で全てを書くことももちろん不可能ではないですが、自動生成をすることが必要となってくるでしょう。

データベースのテーブル作成、変更、削除については多種多様なツールがあり(例えばMySQLAdmin)、それらを用いて行うのが通常だと思われます。

その変更点の差分を取ることによって、バージョンの自動生成を行うことになります。

差分を生成するには

cake migration generate

コマンドを叩きます。

基本的にはy, nを入力(テーブルの比較をするか、プレビューをするか)の後、最後にバージョンの名前を指定すると、バージョンが生成されます。

モデルが無いテーブル

デフォルトではモデルがあるテーブルのみが自動生成の対象となります(schemaと一緒ですね)。

これを回避するには、-f(force)オプションを指定します。

cake migration generate -f
Schemaファイルとバージョンの生成

バージョンの自動生成をする際、Schemaファイルがあると(app/config/schema/schema.php)、それと現在のDBスキーマを比較します。

逆にSchemaファイルが無いと、全てのテーブルがバージョンとして生成されます

つまり、差分をうまく吐くにはSchemaファイルが必要になってきます。

従って、バージョンを吐いた後に、スキーマファイルも(必要であれば上書きして)生成しておく必要があります。

cake migration generate -f
cake schema generate -f

さて、最初のバージョンを作成する方法は二通り考えられるでしょう。

  • 初期スキーマをまずSchemaファイルに書く
  • 初期スキーマをMigraionの一番目のバージョンファイルに書く

1番目の方法を取ると、ある大きな問題にぶち当たります

それは(例えば本番環境で)最初から一気にスキーマ適用しようとした時、Schemaファイルを実行するしか術が無いということです。

そして、Migrationsのバージョン管理(schema_migrationsテーブル)は、「何も適用されていない」ということになります。

これは次のバージョンアップがある場合、バージョンを適用するだけとはいかず、Migrationsを実行した場合と差異が出る場合があります。

これを避ける為に、2番目の方法を取る必要があります。

従って、以下のフローをお勧めします:

  1. MySQLAdminなどを使ってテーブルの作成
  2. Migrationバージョンの生成
  3. 次に差分を自動するためのSchemaファイルの生成

トピックブランチごとのバージョン管理

トピックブランチでスキーマの変更がある場合、そのトピックブランチ一つごとにバージョンを作成することは良い習慣となります。

トピックブランチを作業ブランチに取り入れた後、スキーマのバージョンを最新にするには以下のコマンドを実行します。

cake migration run all

ここまでは素直なフローですが、あるトピックブランチで新しいバージョンを適用した後、そのトピックブランチが適用されるまでに、他のトピックブランチで作業をしたい場合もあるかと思います。

そこでスキーマバージョンのダウングレードを行います。

cake migration run down

例えば上記を実行することでこれは達成できます。

注意することは、トピックブランチを移動する前にこれを実行しなければならないということです。

移動した後では、差分の情報があるファイルが失われてしまい、ダウングレードが正常にできないためです。

コールバックを用いた不整合の起きないバージョンの作成

Migrationsプラグインの大きな特徴はコールバックの整備です。

コールバックをふんだんに使うことによって、うまく整合性を保つことが運用において最重要となります。

初期レコード

Migrationsを使う場合、初期レコードの生成・更新はバージョンのコールバックを使って行うべきです。

Schemaでもこれは行えるのですが、バージョンごとに管理できる分だけMigrationsならリリースごとに初期レコードを挿入できる分非常に便利です。

初期レコードの更新を行う方法は様々ですが、レコード配列でもっておき、それを挿入・更新するような実装になっていれば良いでしょう。

上記(抜粋)は一例です。

プライマリーキーの変更

静的なテーブルで、プライマリーキーを例えば整数からUUIDに変更したい場合*6、関連するモデルの外部キーも変更したいところです。

これを行うにあたって、InnoDBで外部キー制約をつけている場合、外部キー不整合が起きる為、エラーが起きることがあります*7

これを回避するために、そもそも外部キー制約をしないというのがひとつの方法となり得ます。

しかし、既に外部キー制約を用いたセットアップをしてある場合は一筋縄ではいかないでしょう。

そこで外部キー制約を一旦削除して、レコードの更新などを行なってから元に戻す、ということが必要になります*8

例の抜粋をあげます:

汎用化してる為見難いですが、やってる事自体は単純です!

最後に

その他、CSVからデータを読むも良し、fixturesを使うのも良し(テーブルのdropがされるのを回避できれば)です。

他にもCakeMigrationを継承したクラスで、共通のコールバックが定義できるなど、非常に柔軟で自由な制御ができます。

やりたいことを叶えるのに必要なのは、あなたのイマジネーションだけです!

プロジェクトに合わせた、自在なコントロールを叶えましょう。

21日目のCakePHP Advent Calendar 2011は、ogaaaanさんです。よろしくお願いします。

*1:特定の機能・修正についてのブランチ

*2データベース設計を完全にしてから開発に入る?本当にそれで最後までうまくいった試しがありますか?

*3:例えばテスト環境、別の開発者の開発環境

*4:時系列順と捉えて良い

*5:schema_migrationsという、バージョンが適用されたかをMigrationsが管理するためのテーブルを除く

*6:実話

*7:実話

*8:SET FOREIGN_KEY_CHECKS=0が効かないのは周知の事実なのかやり方が間違ってるのか誰か教えて!

2011/12/04

英語に自信がなくてもできるCakePHPへの貢献 -バグ報告編-

CakePHP(またはオープンソースプロダクト)のコアコードバグ・不満・修正・設計について言及したい、しかし英語わからない、面倒くさい、なんとなく怖い、といった方向け。

導入

CakePHPへの貢献は色々な方法があります。バグ報告、パッチドキュメント、議論、有用プラグインの作成、etc..

といっても、英語書かなきゃいけないというプレッシャーは大きいはず。

しかし怖がることはありません!

最低限の情報提供だけでもそれは有益なことです。

私たちの使っているフレームワークコミュニティにはたくさんの、英語のネイティブではない人々がおり、その人達によってCakePHPは支えられているのです。

バグ報告

CakePHPへの貢献の中で、まず一番簡単で楽なのはなんといってもバグ報告です。

今回はこのバグ報告について、実例を見ながら、どうすればバグ報告をできるかを説明します。

チケット管理システム

CakePHPバグトラック、またはチケット管理のシステムLighthouseホストされており、そのCakePHP専用のサイトは

http://cakephp.lighthouseapp.com/projects/42648-cakephp/overview

にあります。

アカウントが無い場合は作成しましょう。

※フォームの最後の項目で簡単なクイズがありますが、これは例えばお伽話のフレーズの一部の単語などとなっており、英語圏で生活していないと難題だったりします。しかし、フレーズを検索すればすぐ出てくるようなものばかりなので、ググりましょう

アカウントを作成したら、ログインしてください。

dashboardにいる場合は、報告したいプロジェクトを選択します。

f:id:hiromi2424:20111204152734p:image

右側のサイドバーに「Create new ticket」というボタンが見えます。これをクリックして新規チケットを発行する画面に移ります。

f:id:hiromi2424:20111204152735p:image

またこのボタンの下にある注意書きも見ておきましょう。

バグ報告時に気をつけること

When creating a bug report, please include as much relevant information as possible. Please include code to reproduce the issue. Or even better, make a unit test. Either change an existing test or add a new test to show that the expected behavior is not occuring.

訳:バグ報告を作成する際には、できるだけ多くの関連情報を記載してください。また、ユニットテストを行うこともより好ましいです。これは既存のテストを変更するか、期待する動作が起こっていないことを示すテストを追加するということです。

さて、自分が発行したとあるチケットを例として見ながら、フォームを入力していきましょう。

http://cakephp.lighthouseapp.com/projects/42648/tickets/2285-relative-protocol-url-was-replaced-by-asset-filter

入力する必要があるのは、タイトル、本文だけです。

タイトル

適切でわかりやすい一文にすることがベストですが、自動翻訳にかけるか、単語の羅列でも構わないでしょう。

ちなみに例では時制が過去形となっていて違和感があるというか明らかに間違ってますが、こんないい加減さでも伝わるもんは伝わります。(べ、別にわざとじゃなくて素なんだからね

本文

初期状態で、既に3つの見出しがついています。

先頭の#が4つついているのはマークダウン形式の見出しレベルの指定で、これはh4を表します。

この直下に伝えたいことを述べましょう。

#### What I did(自分がしたこと)

自分が試した例を挙げます。

再現性が高いものが望ましいです。

特定の環境でしか起きないならばその環境も書きましょう。(OSとか、バージョンとか

単純に、ファイルの特定行を抜き出して書くだけでもいいでしょう。

例では、

app/Config/core.php:
Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
view:
<?php echo $this->Html->script('//example.com/js/hoge.js'); ?>

としても良かったことでしょう。


#### What happened(何が起こったか)

上記で試したことによって起こった結果を書きましょう。

これには出力、トレース、ログなどを含めてなるべく細かに報告したほうが良いです。(英語をいっぱい書けというわけではありません)

「エラーが起きた」「動かない」だけだと何も伝わりませんね。これは日本語でも同じです。

例では出力されたHTMLソースからコピーしたものを貼りつけています。

どれを見せたらいいかわからない場合などは、画面キャプチャ画像を添付するのもいいでしょう。フォームの最後のところに添付するファイルの入力が用意されています。


#### What I expected to happen(何が起こると期待したか)

こうなって欲しい、ということを書きます。

例ではまたしても時制が(中の人の英語力が知れますね)・・・まあ主語と目的語があればなんとなく伝わります。

パッチを書いてあれば、それを載せるのもいいでしょう。これにはCakeBingistフォークしたレポジトリのトピックブランチを活用しましょう。


その他

他に言いたいことがあれば、見出しを追加して書きましょう。

または、テンプレートを消して1から書いてももちろん問題ありません。

最後に感謝を述べるのも良い習慣です。どんなに小さくとも感謝の言葉は嬉しいものです。#で、あんたはやってるの?っていう質問は締め切りました


その他の項目

Who's responsible?(誰が担当?)や、タグについては、運営側が補完してくれることがほとんどで、出来る範囲でその助けとなるようにタグを書くだけで良いでしょう。

担当については、こちらで勝手に指定してしまうと、「なんでやねん」ってことになることがほとんどなので、もし特定のコア開発者と会話した後などであっても、指定しないようにしましょう。

その後

フォームを送信(右下にある「CREATE TICKET」のボタンをクリック)した後は、運営側がまずそのチケットを評価します。

  • 報告が間違ってる(invalid)
  • 保留(hold)
  • こっちでは問題ない(works-for-me)
  • 修正されない(won't-fix

などのステータスが付与されるか、new(新規)のまま解決(resolved)を待つことになります。

この時にタグマイルストーン、担当などを設定してくれることでしょう。

更に、それが問題として認識されれば、コアチーム中心にその解決のためのコミットが作成され、コードに反映されます。

あなたが解決する必要はありません。出来る人がやる、それが原則です。(もちろん、あなたが解決策、パッチを提供することは非常に助けになり、大切なことです)

最後に

ネットのコミュニケーションでもボディーランゲージは非常に有効です。

また、私達にはコードという最大の共通言語があります。

何も難しいことはありませんね!誰にでもバグ報告はできます

コアのコードの一部をあなたのプロジェクト固有に変更するという暴挙を繰り返したりなどする必要はないのです。

共通のプロジェクトへの貢献こそが、人々、またはあなた自身の大切な財産となり、全てにわたって最上の利益となるベストプラクティスなのです。

2011/11/29

CakePHP 2.0.4がリリースされました(訳)

この新しいバージョンは2.xブランチの重要なセキュリティ修正が含まれています。

できうる限り早くアプリケーションアップグレードすることを強く推奨いたします。

CakePHPコアチームはCakePHP2.0.4*1を素早くリリースできたことを誇りに思います。

このリリースにはAuthComponentの重要なセキュリティ問題の修正があります。

このバージョンより前は、コントローラで定義されたものとURLでのアクション名で大文字・小文字が異なるものを用いた場合、AuthComponentがログインしていないユーザを保護されたアクションに通らせていました。

2.0.xのいずれものバージョンをお使いになっている方々はできうる限り早くこのバージョンを使うようにアプリケーションアップグレードすることを強く推奨いたします。

2.0.4では合計で、60のコミットがあり、20の問題が解決されました。変更ログページ*2で完全な変更のリストを見ることができますが、以下は2.0.4でされた変更の簡単な要約となります:

2.1ブランチは良いスピードで進行しており、とても早くこのブランチの初期アルファ版をお届け出来ると思っています。

全ての関連するコミット、チケット、ドキュメントの編集、その他フレームワークへの助力を通しての貢献に関して、多大な感謝を捧げます。あなたがいなければ、CakePHPはなかったことでしょう!

後書き

Bakeryのリリース記事の訳です。

http://bakery.cakephp.org/articles/lorenzo/2011/11/28/cakephp_2_0_4_released

またもや重要なセキュリティ修正になります。

ユーザの情報が取得できなかった場合、表示してはいけない情報が表示されるような作りになっていると呪われるので早めにアップデートしましょう。

2011/11/14

CakePHP 2.0.3 が焼きあがりました(訳)

このCakePHPの新しいバージョンは2.0ブランチへの安定性の向上と、PHPUnit 3.6の完全な互換性、PHP5.4のサポートをもたらします。

CakePHPコアチームは迅速にCakePHP2.0.3*1が利用可能になったことを誇りに思います。前のリリースからPHPの世界に多くのことが起き、この新バージョンにはPHPフレームワークの進化し続ける世界に適応するために必要なすべての変更が組み込まれています。

大きな変更があったうちの一つは、PHPUnit 3.6が安定版になりPEARインストーラを通したデフォルトのバージョンとなったことです。この変更は多くの開発者にとって驚きとなりました。PHPUnitの主要な変更により開発者はCakePHP組み込みテストスイートを実行するのが難しくなりました。PHPUnitの3.5と3.6の両方のバージョンで問題が起きないように2.0.3が確実に実行できるように必要な変更を加えました。

全ての出力がPHPUnitに吸収されWEBテストページやCLIテストのどちらでも表示されないということが多くの人が単体テストを書く時に気づくであろう大きな違いとなります。このやっかいごとを乗り越えるには、CLIインターフェースを使っているときに--debug修飾子を使ってください。

2番目の良いニュースはPHP5.4-rc1が利用可能になったことです。このPHPバージョンに対する私たちのフレームワークをテストするのに時間をかけ、自動テストを実行中に発見された多くの細かい警告(notice)や問題を修正しました。もしあなたが早くも5.4に飛びついているとすると、CakePHPがその中でスムーズに実行できるフレームワークの一つと考えることもできるでしょう。

2.0.3では合計で、66のコミットがあり、32の問題が解決されました。変更ログページ*2で完全な変更のリストを見ることができますが、以下は2.0.3でされた変更の簡単な要約となります:

  • PHP5.4でのスムーズな実行
  • RESTを用いたコントローラのテスト
  • DboSource::insertMulti()で真偽値の正しい操作
  • PHPUnit 3.6の完全な互換性
  • いくつかのコマンドラインのbakeユーティリティの小さな問題の修正
  • レスポンスの本文の前に送られるバッファ出力がある時のContent-Lengthの計算の修正
  • UpgradeShellでの種々の向上
  • DboSource::lastAffected()が正しい整数を返すようになった

CakePHPへの増え続ける関心に感謝します。コードとドキュメント両方に多くのプルリクエストを受け取り、この新バージョンを作成している話題全てに興奮を覚えました。あなた方全ての貢献がなかったら、CakePHPはなかったことでしょう。

後書き

Bakeryのリリースノートの訳です

http://bakery.cakephp.org/articles/lorenzo/2011/11/14/cakephp_2_0_3_out_of_the_oven

私的にですが、2.0.2まではPHPUnit3.6のサポートが無く、Jenkins(旧Hadson)がうまく動かせないなどして困っていたのでこの迅速なサポートは非常に有難いところです。

ドキュメントのほうでも、ロシア語が追加され、また多くのコミットがあり活気だっています。

勢いに衰えが見えないところが素晴らしいですね。

新しいマニュアルを翻訳するのは、元(cookbookのCakePHP <= 1.3)からコピーする部分も多く非常に簡単なので、是非参加してみてください。

#あと、TransitionComponentをforkした人はさっさとpull requestを(