Skip to content
Caution: You are browsing the legacy symfony 1.x part of this website.

symfony 1.3では何が新しくなったの?

Symfony version
Language

このチュートリアルではsymfony 1.3のための技術的な内容をおおまかに紹介します。 このチュートリアルはsymfony 1.2ですでに作業をしており、symfony 1.3の新しい機能を速く学びたい開発者向けです。

最初に、symfony 1.3はPHP 5.2.4とそれ以降と互換性があることにご注意ください。

1.2からアップグレードしたいのであれば、symfonyの配布ファイルの中で見つかるUPGRADEファイルをご覧ください。 プロジェクトをsymfony 1.3に安全にアップグレードするために必要なすべての情報が手に入ります。

メーラー

symfony 1.3ではSwiftMailer 4.1に基づく新しい標準のメーラーが用意されました。

Eメールの送信はシンプルでアクションからcomposeAndSend()メソッドを使うだけです:

$this->getMailer()->composeAndSend('from@example.com', 'to@example.com', 'Subject', 'Body');

より柔軟性をもたせるなら、compose()メソッドを使い後で送信することができます。メッセージに添付ファイルを追加する方法は次のとおりです:

$message = $this->getMailer()->
  compose('from@example.com', 'to@example.com', 'Subject', 'Body')->
  attach(Swift_Attachment::fromPath('/path/to/a/file.zip'))
;
$this->getMailer()->send($message);

メーラーはとても強力なので、詳細な情報は公式マニュアルを参照してください。

セキュリティ

generate:appタスクで新しいアプリケーションをつくるとき、セキュリティー設定はデフォルトで有効になるようになりました:

  • escaping_strategy: この値はデフォルトでtrueです(--escaping-strategyオプションで無効にできる)。

  • csrf_secret: デフォルトでランダムなパスワードが生成されます。 CSRFの保護機能は標準で有効です(--csrf-secretオプションで無効にすることができます)。 settings.yml設定ファイルを編集するか、--csrf-secretオプションを使う事で、デフォルトのパスワードを変更することが強く勧められます。

ウィジット

標準のラベル

ラベルがフィールド名で自動生成された場合、サフィックスの_idは削除されます:

  • first_name => First name (以前と同じ)
  • author_id => Author (以前は "Author id" )

sfWidgetFormInputText

sfWidgetFormInputクラスは抽象クラスになりました。 テキスト入力フィールドはsfWidgetFormInputTextクラスで作られます。 この変更によってフォームクラスの内観はより簡単になりました。

国際化ウィジェット

次のウィジェットが追加されました:

  • sfWidgetFormI18nChoiceLanguage
  • sfWidgetFormI18nChoiceCurrency
  • sfWidgetFormI18nChoiceCountry
  • sfWidgetFormI18nChoiceTimezone

これらの最初の3つは廃止予定のsfWidgetFormI18nSelectLanguagesfWidgetFormI18nSelectCurrencysfWidgetFormI18nSelectCountryウィジェットの置き換えです。

流れるようなインターフェイス

ウィジットは次のように流れるようなインターフェイスを実装するようになりました:

  • sfWidgetForm: setDefault(), setLabel(), setIdFormat(), setHidden()

  • sfWidget: addRequiredOption(), addOption(), setOption(), setOptions(), setAttribute(), setAttributes()

  • sfWidgetFormSchema: setDefault(), setDefaults(), addFormFormatter(), setFormFormatterName(), setNameFormat(), setLabels(), setLabel(), setHelps(), setHelp(), setParent()

  • sfWidgetFormSchemaDecorator: addFormFormatter(), setFormFormatterName(), setNameFormat(), setLabels(), setHelps(), setHelp(), setParent(), setPositions()

バリデーター

sfValidatorRegex

sfValidatorRegexは新しいmust_matchオプションを持ちます。 falseにセットされる場合、正規表現は渡すバリデーターにマッチしません。

sfValidatorRegexpatternオプションは呼び出し時に正規表現を返すsfCallableのインスタンスにしなければならなくなりました。

sfValidatorUrl

sfValidatorUrl は新しい protocols オプションを持つようになりました。 次のように特定のプロトコルを許可することができるようになりました:

$validator = new sfValidatorUrl(array('protocols' => array('http', 'https')));

つぎのプロトコルがデフォルトで許可されています:

  • http
  • https
  • ftp
  • ftps

sfValidatorSchemaCompare

sfValidatorSchemaCompare クラスは2つの新しいコンパレーターを持つようになりました。:

  • IDENTICAL、は===と同等;
  • NOT_IDENTICAL、は!==と同等;

sfValidatorChoice, sfValidatorPropelChoice, sfValidatorDoctrineChoice

sfValidatorChoice、 sfValidatorPropelChoiceそしてsfValidatorDoctrineChoiceバリデーターはmultipleオプションがtrueの場合のみ有効になる2つの新しいオプションを持ちます:

  • min 選択される必要がある最小の数
  • max 選択される必要がある最大の数

I18n バリデーター

次のバリデーターが追加されました:

  • sfValidatorI18nTimezone

標準のエラーメッセージ

次のようにsfForm::setDefaultMessage()メソッドを使うことでグローバル領域で 標準のエラーメッセージを定義できるようになりました。:

sfValidatorBase::setDefaultMessage('required', 'This field is required.');

以前までのコードは標準のRequired.メッセージを全てのバリデータのために上書きするでしょう。 標準のメッセージはどのバリデータが作成される前に定義しておかなければならないことに注意してください (コンフィグレーションクラスが良い場所です)。

note

setRequiredMessage()setInvalidMessage()メソッドは 非推奨になり、新しいsetDefaultMessage()メソッドを呼ぶようになりました。

symfonyがエラーを表示するとき、次のように使用されるエラーメッセージは決定されます。:

  • symfonyはバリデーターが作成されたときに通過したメッセージを探します。 (バリデーターのコンストラクターの第2引数を通して);

  • 定義されていないなら、setDefaultMessage()メソッドで標準の定義されたメッセージを探します。;

  • もし、定義されていないなら、(メッセージがaddMessage()メソッドで追加され ているとき)バリデーター自身で定義された標準のメッセージへ戻ります。

流れるようなインターフェイス

バリデーターは次のように流れるようなインターフェイスを実装するようになりました:

  • sfValidatorSchema: setPreValidator()setPostValidator()

  • sfValidatorErrorSchema: addError()addErrors()

  • sfValidatorBase: addMessage()setMessage()setMessages()addOption()setOption()setOptions()addRequiredOption()

sfValidatorFile

php.inifile_uploadsが無効な場合sfValidatorFileのインスタンスを作成するときに例外が投げられます。

フォーム

sfForm::useFields()

新しいsfForm::useFields()メソッドはフォームから引数として提供されるもの以外、すべてのhiddenではないフィールドを削除します。 状況によって不要なフィールドの割り当てを解除する代わりにフォームで維持したいフィールドを明示的に指示するのが楽になります。 たとえば、新しいフィールドを基底フォームに追加するとき、これらは明示的に追加されるまでフォームで自動的に現われなくなります(モデルフォームで新しいカラムを関連テーブルに追加するを考えてください)。

class ArticleForm extends BaseArticleForm
{
  public function configure()
  {
    $this->useFields(array('title', 'content'));
  }
}

デフォルトでは、フィールドの配列はフィールドの順序を変更するためにも使われます。 自動的な順序づけを無効にするには2番目の引数としてfalseuseFields()に渡します。

sfForm::getEmbeddedForm($name)

->getEmbeddedForm()メソッドを使って特定の組み込みフォームにアクセスできます。

sfForm::renderHiddenFields()

->renderHiddenFields()メソッドは組み込みフォームからの隠しフィールドをレンダリングします。

sfFormSymfony

新しいsfFormSymfonyクラスはイベントディスパッチャーをsymfonyフォームに導入します。 self::$dispatcherをとおしてフォームクラス内部のディスパッチャーにアクセスできます。 次のフォームイベントはsymfonyによって通知されます:

  • form.post_configure: このイベントはフォームが設定された後で通知される
  • form.filter_values: このイベントは、マージされ汚染されたパラメーターと、バインドする直前のファイルの配列をフィルタリングする
  • form.validation_error: フォームバリデーションが失敗するときこのイベントが通知される
  • form.method_not_found: 未知のメソッドが呼び出されるときにこのイベントが通知される

BaseForm

symfony 1.3のすべての新しいプロジェクトにはFormコンポーネントを拡張するもしくはプロジェクト固有の機能を追加するために使うことができるBaseFormクラスが入ります。 sfDoctrinePluginsfPropelPluginによって生成されるフォームは自動的にこのクラスを継承します。 追加のフォームクラスを作るのであればsfFormよりもBaseFormを継承すべきです。

sfForm::doBind()

汚染されたパラメーターのクリーニングは開発者にやさしい->doBind()メソッドに隔離されました。 このメソッドは->bind()からのパラメーターとファイルのマージされる配列を受け取ります。

sfForm(Doctrine|Propel)::doUpdateObject()

DoctrineとPropelのフォームクラスは開発者が扱いやすい->doUpdateObject()メソッドを含むようになりました。このメソッドは->updateObject()から->processValues()ですでに処理された値の配列を受け取ります。

sfForm::enableLocalCSRFProtection() and sfForm::disableLocalCSRFProtection()

sfForm::enableLocalCSRFProtection()sfForm::disableLocalCSRFProtection()メソッドを使うとき、あなたのクラスのconfigure()メソッドから簡単にCSRFからの保護機能を設定することができます。

CSRFからの保護機能を無効にするためには、次のような行をconfigure()メソッドに追加します:

$this->disableLocalCSRFProtection();

disableLocalCSRFProtection()をコールすることによって、フォームインスタンスを作成するときにCSRFシークレットを渡していたとしてもCSRFからの保護機能は無効になります。

流れるようなインターフェイス

sfForm メソッドは次のような流れるインターフェイスを実装するようになりました: addCSRFProtection(), setValidators(), setValidator(), setValidatorSchema(), setWidgets(), setWidget(), setWidgetSchema(), setOption(), setDefault(), そして setDefaults().

オートローダー

symfonyのすべてのオートローダーは大文字と小文字を区別しないようになりました。 PHPが大文字と小文字を区別をしませんし、symfonyはそれに合わせまるようになりました。

sfAutoloadAgain (実験的)

デバッグモードでの用途を目的とする特殊なオートローダーが追加されました。 新しいsfAutoloadAgainクラスはsymfonyの標準オートローダーをリロードし問題のクラスを求めてファイルシステムを検索します。 純粋な効果は新しいクラスをプロジェクトに追加した後にsymfony ccを実行する必要はないことです。

テスト

テストのスピードアップ

大規模なテストスイートの場合、変更するたびに全てのテストを起動するのはとても時間を消費するはずです。特にテストが失敗した場合などはそうでしょう。なぜならテストを修正するたびに、何も壊していないことを確認するためにテストスイート全体を再度実行すべきだからです。しかし、テストが修正されない限り、全てのテストを再実行する必要はありません。symfony1.3ではtest:allsymfony:testタスクが前回の実行時に失敗したテストだけを再実行する--only-failed(-fがショートカットになります)オプションを持つようになりました:

$ php symfony test:all --only-failed

どのように動作するかを説明します: まず最初に、全てのテストはいつも通りに実行されます。しかし引き続きテストを実行しても、最後のテストで失敗したものだけが実行されます。コードを修正したら、テストは通過し次回以降の実行からは除外されるかもしれません。 再び全てのテストがパスしたら、あなたは完全なテストスイートを実行し。。。洗い流し繰り返すことができます。

機能テスト

リクエストが例外を生成するとき、レスポンステスターのdebug()メソッドは標準的なHTML出力の代わりに、人間が読めるような例外のテキストの説明を出力するようになりました。 より簡単にデバッグできるようになります。

sfTesterResponseはレスポンスの内容全体に対して正規表現で検索を行える新しいmatches()メソッドを持つようになりました。 XMLのようでないレスポンス、それはcheckElement()が使えないようなレスポンスですが、そういった場合にとても役立ちます。ひ弱だったcontains()メソッドの代わりにも使うことができます。:

$browser->with('response')->begin()->
  matches('/I have \d+ apples/')->    // it takes a regex as an argument
  matches('!/I have \d+ apples/')->   // a ! at the beginning means that the regex must not match
  matches('!/I have \d+ apples/i')->  // you can also add regex modifiers
end();

JUnitと互換性のあるXML出力

テストタスクは--xmlオプションを使うことでJUnit互換のXMLファイルを出力することもできるようになりました。:

$ php symfony test:all --xml=log.xml

簡単なデバッグ

テストハーネスがテストが失敗したことを報告するときデバッグを簡単にするために、失敗について詳細な出力ができる--traceオプションを渡すことができるようになりました:

$ php symfony test:all -t

Limeの出力の色づけ

symfony1.3では、limeはカラー化に関していえば正しく行うようになりました。これが意味する事は、lime_testのlimeコンストラクターの第2引数をほとんどいつも省略することができるということです:

$t = new lime_test(1);

sfTesterResponse::checkForm()

レスポンステスターはより簡単にフォームにある全てのフィールドがレスポンスに正しくレンダリング処理されているかどうかを確認できるメソッドを含むようになりました:

$browser->with('response')->begin()->
  checkForm('ArticleForm')->
end();

もしくは、フォームオブジェクトを渡すことができます:

$browser->with('response')->begin()->
  checkForm($browser->getArticleForm())->
end();

レスポンスがmultipleフォームを含む場合は、どのDOM部分をテストするかをピンポイントで指定するためにCSSセレクターを提供するためのオプションがあります:

$browser->with('response')->begin()->
  checkForm('ArticleForm', '#articleForm')->
end();

sfTesterResponse::isValid()

レスポンスが整形式XMLであるかをレスポンステスターの->isValid()メソッドでチェックできます:

$browser->with('response')->begin()->
  isValid()->
end();

引数としてtrueを渡すことでドキュメントの種類に対するレスポンスをバリデートすることもできます:

$browser->with('response')->begin()->
  isValid(true)->
end();

代わりに、バリデートするXSDもしくはRelaxNGスキーマがある場合、ファイルへのパスを提供できます:

$browser->with('response')->begin()->
  isValid('/path/to/schema.xsd')->
end();

context.load_factoriesをリスニングする

機能テストにcontext.load_factoriesイベントへのリスナーが追加されました。 これまでのsymfonyのバージョンではできませんでした。

$browser->addListener('context.load_factories', array($browser, 'listenForNewContext'));

よりよい->click()

->click()メソッドにCSSセレクターを渡すことが可能で、セマンティックにしたい要素をターゲットにするのが楽になります。

$browser
  ->get('/login')
  ->click('form[action$="/login"] input[type="submit"]')
;

タスク

symfonyのCLIはターミナルウィンドウの幅を検出しようとし、ラインのフォーマットを合わせようとします。検出できない場合はCLIは標準の78カラム幅に合わせようとします。

sfTask::askAndValidate()

ユーザーに質問し入力された内容をバリデートするsfTask::askAndValidate()メソッドが新しくできました。:

$anwser = $this->askAndValidate('What is you email?', new sfValidatorEmail());

このメソッドはオプションの配列を受ける事もできます(より詳しい情報はAPIドキュメントを参照)。

symfony:test

ときどき、開発者は特定のプラットフォーム上でsymfonyが正しく動作するかチェックするためにsymfonyのテストスイートを実行する必要があります。今までは、symfonyに附属しているprove.phpスクリプトを実行し確認しなければなりませんでした。 symfony1.3では組み込みのタスク、コマンドラインからsymfonyのコアテストスイートを起動できるsymfony:testタスクが用意され、他のタスクと同じように使うことができます:

$ php symfony symfony:test

php test/bin/prove.phpに慣れているならば、同等のphp data/bin/symfony symfony:testコマンドを実行できるようになっています。

project:deploy

project:deplyタスクはわずかに改良されました。リアルタイムでファイルの転送状況を表示するようになりました。ただし、-tオプションが渡されたときだけです。もしオプションが指定されていなければタスクは何も表示しません、もちろんエラーは除きます。エラー時には、エラーについて出力し簡単に問題を認識できるように赤色の背景上に出力します。

generate:project

symfony1.3では、generate:projectタスクを実行するときDoctrineが標準の設定されたORMになります:

$ php /path/to/symfony generate:project foo

Propelのためにプロジェクトを生成するためには、--ormオプションを使います:

$ php /path/to/symfony generate:project foo --orm=Propel

PropelもDoctrineのどちらも使いたくない場合は、--ormオプションにnoneを渡すことができます:

$ php /path/to/symfony generate:project foo --orm=none

新しい--installerオプションのおかげで新しく生成されるプロジェクトをかなりカスタマイズできるPHPスクリプトを指定することができます。スクリプトはタスク内で実行され、タスクのメソッドで使う事ができます。より利用できるメソッドは次のようなものです。:installDir(), runTask(), ask(), askConfirmation(), askAndValidate(), reloadTasks(), enablePlugin(), and disablePlugin().

より詳細な情報は公式ブログの記事にあります。

プロジェクトを生成するとき、2番目の"著者"の引数を含めることができます。which specifies a value to use for the @author doc tag when symfony generates new classes.

$ php /path/to/symfony generate:project foo "Joe Schmo"

sfFileSystem::execute()

sfFileSystem::execute()メソッドはsfFileSystem::sh()メソッドをより強力な機能で置き換えます。stdoutstderr出力のプロセスをリアルタイムでコールバックします。配列で両方の出力を返すこともできます。sfProjectDeployTaskクラスで使い方の1例を見つけることができます。

task.test.filter_test_files

test:*タスクはこれらのタスクが実行される前にtask.test.filter_test_filesイベントを通過するようになりました。 このイベントにはargumentsoptions パラメーターがあります。

sfTask::run() の強化

sfTask:run()に次のような引数の連想配列とオプションを渡すことができるようになりました:

$task = new sfDoctrineConfigureDatabaseTask($this->dispatcher, $this->formatter);
$task->run(
  array('dsn' => 'mysql:dbname=mydb;host=localhost',
), array(
  'name' => 'master',
));

これまでのバージョンでは、次のようにすればまだ動作します:

$task->run(
  array('mysql:dbname=mydb;host=localhost'),
  array('--name=master')
);

sfBaseTask::setConfiguration()

PHPからsfBaseTaskを拡張しているタスクをコールするとき、->run()--application--envオプションを渡す必要はもうありません。 その代わりに、ただ->setConfiguration()をコールするだけで直接設定オブジェクトをセットすることができます。

$task = new sfDoctrineLoadDataTask($this->dispatcher, $this->formatter);
$task->setConfiguration($this->configuration);
$task->run();

これまでのバージョンでは、次のようにすればまだ動作します:

$task = new sfDoctrineLoadDataTask($this->dispatcher, $this->formatter);
$task->run(array(), array(
  '--application='.$options['application'],
  '--env='.$options['env'],
));

project:disableproject:enable

project:disableproject:enableタスクを使うことで環境全体を無効、または有効にすることができるようになりました:

$ php symfony project:disable prod
$ php symfony project:enable prod

環境においてどのアプリケーションを無効にするかを指定することもできます:

$ php symfony project:disable prod frontend backend
$ php symfony project:enable prod frontend backend

これらのタスクはこれまでの機能と後方互換があります:

$ php symfony project:disable frontend prod
$ php symfony project:enable frontend prod

helplist

helplistタスクはXMLで情報を表示することができるようになりました:

$ php symfony list --xml
$ php symfony help test:all --xml

この出力は新しいsfTask::asXml()メソッドに基づいており、これはタスクオブジェクトのXML表現を返します。

XML出力はIDEのようなサードパーティーにとって大抵の場合においてとても役立つでしょう。

project:optimize

このタスクを実行すればアプリケーションのテンプレートファイルの位置をキャッシュすることで実行時のディスクの読み込み回数を減らします。 このタスクは運用サーバーでのみ使われます。 プロジェクトを変更するたびにタスクを再実行することをお忘れなく。

$ php symfony project:optimize frontend

generate:app

generate:appタスクはコアに搭載されるデフォルトのスケルトンディレクトリの代わりにプロジェクトのdata/skeleton/appディレクトリのスケルトンディレクトリをチェックします。

タスクからEメールを送信する

getMailer()メソッドを使うことでタスクからEメールを簡単に送信することができます。

タスクでルーティングを使う

getRouting()メソッドを使うことでタスクからルーティングオブジェクトを簡単に取得できます。

例外

オートローディング

オートロードの間に例外が投げられるとき、symfonyはこれらを捕らえエラーをユーザーに出力します。 これは一部の"真っ白な"ページの問題を解決します。

Webデバッグツールバー

可能であれば、Webデバッグツールバーは開発環境の例外ページに表示されます。

Propel統合

Propelはバージョン1.4にアップグレードされました。Propelのアップグレードに関する詳しい情報は公式サイトを訪問してくださるようお願いします。

Propelのビヘイビア

Propelを拡張するためにsymfonyが依存するカスタムのビルダークラスはPropel 1.4の新しいビヘイビアシステムに移植されました。

propel:insert-sql

propel:insert-sqlがデータベースから全てのデータを削除する前に確認を行います。 このタスクは複数のデータベースからデータを削除することができるので、関連するデータベースの接続名も表示するようになりました。

propel:generate-modulepropel:generate-adminpropel:generate-admin-for-route

propel:generate-modulepropel:generate-adminpropel:generate-admin-for-routeタスクは生成モジュールのアクション基底クラスのコンフィギュレーションを可能にする--actions-base-classオプションをとります。

Propelのビヘイビア

Propel 1.4はPropelのコードのビヘイビアの実装を導入しました。 カスタムのsymfonyビルダーはこの新しいシステムに移植されました。

PropelモデルネイティブなビヘイビアをPropelモデルに追加したい場合、schema.ymlでもできます:

classes:
  Article:
    propel_behaviors:
      timestampable: ~

もしくは、古いschema.yml構文を使う場合:

propel:
  article:
    _propel_behaviors:
      timestampable: ~

フォーム生成を無効にする

symfonyのPropelビヘイビアにパラメーターを渡すことで特定のモデルでのフォーム生成を無効にできます:

classes:
  UserGroup:
    propel_behaviors:
      symfony:
        form: false
        filter: false

ルーティング

デフォルトの要件

デフォルトの必須要件\d+columnオプションがデフォルトのidになっているときsfObjectRouteCollectionにだけ適用されるようになりました。 (slugのような)数字でないカラムが指定されているとき代わりの必須要件を用意する必要はないということです。

sfObjectRouteCollectionオプション

新しいdefault_paramsオプションがsfObjectRouteCollectionに追加されました。 これはそれぞれの生成ルートに登録されるデフォルトパラメーターを可能にします:

forum_topic:
  class: sfDoctrineRouteCollection
  options:
    default_params:
      section: forum

CLI

出力の色づけ

symfonyのCLIを使用するとき、symfonyはあなたが利用しているコンソールがカラーの出力をサポートしているかどうかを推測しようとします。 しかし、symfonyは推測を間違える場合があります;例えば、Cygwinを使っているときです(Windowsプラットフォームではカラーの出力は常に切られているからです)。

symfony1.3では、--colorグローバルオプションを渡すことでカラーで出力することを強制できるようになりました。

国際化(I18N)

データの更新

すべての国際化オペレーションに使われるデータはICUプロジェクトから更新されました。 symfonyには約330のロケールファイルが付属しており、symfony 1.2と比べると約70増えています。 ですのでたとえば、言語リストの10番目の項目をチェックするテストケースが失敗する可能性があることにご注意をお願いします。

ユーザーロケールを基準にソートする

このロケールに依存するデータでのすべてのソートもロケールに依存して実行されます。 この目的のためにsfCultureInfo->sortArray()を使うことができます。

プラグイン

symfony 1.3以前では、sfDoctrinePluginsfCompat10Plugin以外のすべてのプラグインはデフォルトで有効にされました:

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // 互換性のために望むプラグインだけ削除および有効にする
    $this->enableAllPluginsExcept(array('sfDoctrinePlugin', 'sfCompat10Plugin'));
  }
}

symfony 1.3で新しく作られたプロジェクトでは、プラグインを使うためにはProjectConfigurationクラスで明示的に有効にしなければなりません:

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->enablePlugins('sfDoctrinePlugin');
  }
}

plugin:installタスクはインストールするプラグインを自動的に有効にします(そしてplugin:uninstallはプラグインを無効にします)。 Subversion経由でプラグインをインストールする場合、手動で有効にする必要があります。

sfProtoculousPluginもしくはsfCompat10Pluginのような コアプラグインを使いたい場合、必要なのは対応するenablePlugins()ステートメントをProjectConfigurationクラスに追加することだけです。

note

1.2からプロジェクトをアップグレードする場合、古いふるまいはアクティブなままです。 これはアップグレードタスクがProjectConfigurationファイルを変更しないからです。 このふるまいの変更はsymfony 1.3の新規プロジェクトのみです。

sfPluginConfiguration::connectTests()

新しいsetupPlugins()メソッドでプラグインの設定の->connectTests()メソッドをコールすることでtest:*タスクにプラグインのテストを接続することができます。

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setupPlugins()
  {
    $this->pluginConfigurations['sfExamplePlugin']->connectTests();
  }
}

設定

sf_file_link_format

symfony 1.3は可能であるときにファイルパスをクリック可能なリンクにフォーマットします(すなわちデバッグ例外のテンプレート)。 sf_file_link_formatはセットされる場合、この目的に使われ、そうでなければ、symfonyはPHP設定のxdebug.file_link_formatの値を探します。

たとえば、TextMateでファイルを開きたい場合、次のコードをsettings.ymlに追加します:

all:
  .settings:
    file_link_format: txmt://open?url=file://%f&line=%l

%fプレースホルダーはファイルの絶対パスに、%lプレースホルダーは行数に置き換えられます。

Doctrineの統合

フォームクラスを生成する

DoctrineのYAMLスキーマファイルにsymfonyのための追加オプションを指定することができるようになりました。 フォームとフィルタークラスの生成を無効にするオプション群を追加しました。

例えば、典型的な多対多の関係のモデルで、フォームやフィルターフォームクラスの生成は必要ないでしょう。そこで、次のように行うことができます。

UserGroup:
  options:
    symfony:
      form: false
      filter: false
  columns:
    user_id:
      type: integer
      primary: true
    group_id:
      type: integer
      primary: true

フォームクラスの継承

あなたのモデルクラスからフォームを生成するとき、モデルクラスは継承を含んでいます。 生成された子クラスは継承を留意し、同じ継承構造に続くフォームを生成します。

新しいタスク

Doctrineで開発するときに手助けしてくれる新しいタスクを導入しました。

モデルテーブルを作成する

指定されたモデルの配列のために個々にテーブルを作成することができるようになりました。 テーブルを削除するときあなたに変わってテーブルを再作成してくれます。 既存のプロジェクト/データベースで新しいモデルを開発するとき、データベース全体を一掃したくなくテーブル群をただ再構築したいときに役立ちます。

$ php symfony doctrine:create-model-tables Model1 Model2 Model3

モデルファイルを削除する

YAMLスキーマファイルでモデルを変更したり、名前を変えたり、使わなくなったモデルを削除したりすることがよくあるでしょう。 このようなことを行ったとき、孤児となったモデル、フォームそしてフィルタークラスができてしまいます。doctrine:delete-model-filesタスクを使うことで、手動でモデルに関連づけられた生成された関連するファイルを掃除することができるようになりました。

$ php symfony doctrine:delete-model-files ModelName

上記タスクは関連する生成されたファイルを見つけ、そのファイルを削除したいかどうかあなたに確認する前にあなたに報告してくれます。

モデルファイルをクリーンにする

doctrine:clean-model-filesタスクで上記プロセスを自動化しどのモデルをディスクに存在し、YAMLスキーマファイルに存在しないかを見つけることができます。

$ php symfony doctrine:clean-model-files

上記コマンドはYAMLスキーマファイルと生成されたモデルやファイルと比較し、どれを削除すべきかを決定します。 これらのモデルはdoctrine:delete-model-filesタスクに伝えられます。自動的に削除する前にどんなファイルが削除されるかの確認を行います。

データをリロードする

データフィクスチャーを再読み込みするとき完全にデータベースを一掃したいことはよくあることです。doctrine:build-all-reloadタスクはこれを行ってくれますが、モデルやフォームやフィルターの生成などの他のタスクを行っているだけです。そして、これは大規模なプロジェクトにおいては時間がかかるでしょう。そこで、単純にdoctrine:reload-dataタスクを使うことができるようになりました。

次のコマンドです。

$ php symfony doctrine:reload-data

これはつぎのコマンド群を実行するのと同等です:

$ php symfony doctrine:drop-db
$ php symfony doctrine:build-db
$ php symfony doctrine:insert-sql
$ php symfony doctrine:data-load

何でもビルドする

新しいdoctrine:buildタスクによって明確にsymfonyやDoctrineに何をビルドしてほしいか指定できます。このタスクは多くの既存するコンビネーションタスク、これらはより柔軟性のある解決法に賛成して非推奨ですが、これらにおいて機能性を複製します。

以下がdoctrine:buildの使い方です:

$ php symfony doctrine:build --db --and-load

これはデータベースを削除(:drop-db)して作成(:build-db)し、schema.ymlにテーブル設定を作成(:insert-sql)し、フィクスチャーデータを読み込み(:data-load)します。

$ php symfony doctrine:build --all-classes --and-migrate

これはモデル(:build-model)、フォーム(:build-forms)、フォームフィルター(:build-filters)を生成し、保留されていたマイグレーション(:migrate)を実行します。

$ php symfony doctrine:build --model --and-migrate --and-append=data/fixtures/categories.yml

モデルを生成(:build-model)し、データベースのマイグレーション(:migrate)を行い、そしてカテゴリーのフィクスチャーデータ(:data-load --append --dir=/data/fixtures/categories.yml)を付け加えます。

より多くの情報はdoctrine:buildタスクのヘルプページを参照してください。

新しいオプション: --migrate

つぎのタスクは --migrateオプションを格納するようになり、doctrine:migrateで入れ子になったdoctrine:insert-sqlタスクを置き換えます。

  • doctrine:build-all
  • doctrine:build-all-load
  • doctrine:build-all-reload
  • doctrine:build-all-reload-test-all
  • doctrine:rebuild-db
  • doctrine:reload-data

doctrine:generate-migration --editor-cmd

doctrine:generate-migrationタスクは簡単に編集で一度だけマイグレーションクラスが生成される--editor-cmdオプションを格納するようになりました。

$ php symfony doctrine:generate-migration AddUserEmailColumn --editor-cmd=mate

この例はマイグレーションクラスを生成しTextMateで新しいファイルを開いています。

doctrine:generate-migrations-diff

この新しいタスクは新旧のスキーマをもとに、完全なマイグレーションクラスを自動的に生成します。

日付のセッターとゲッター

Doctrineの日付とタイムスタンプの値をPHPのDateTimeオブジェクトインスタンスとして取得するための2つの新しいメソッドを追加しました。

echo $article->getDateTimeObject('created_at')
  ->format('m/d/Y');

日付の値もsetDateTimeObjectメソッドをコールし有効なDateTimeインスタンスを渡すだけでセットすることもできます。

$article->setDateTimeObject('created_at', new DateTime('09/01/1985'));

doctrine:migrate --down

doctrine:migrateはスキーマをリクエストされる方向に一回でマイグレートするupdownオプションを含みます。

$ php symfony doctrine:migrate --down

doctrine:migrate --dry-run

データベースがDDLステートメントのロールバックをサポートする場合(MySQLはサポートしない)、新しいdry-runオプションを利用できます。

$ php symfony doctrine:migrate --dry-run

DQLタスクをテーブルのデータとして出力する

これまではdoctrine:sqlコマンドを実行するとただYAML書式で出力されるだけでした。 新しい--tableオプションを追加しました。 このオプションによってデータをテーブル表示で出力することができるようなり、MySQLのコマンドラインの出力に似たものになっています。

それで、つぎのようなことが可能になりました。

$ ./symfony doctrine:dql "FROM Article a" --table
>> doctrine  executing dql query
DQL: FROM Article a
+----+-----------+----------------+---------------------+---------------------+
| id | author_id | is_on_homepage | created_at          | updated_at          |
+----+-----------+----------------+---------------------+---------------------+
| 1  | 1         |                | 2009-07-07 18:02:24 | 2009-07-07 18:02:24 |
| 2  | 2         |                | 2009-07-07 18:02:24 | 2009-07-07 18:02:24 |
+----+-----------+----------------+---------------------+---------------------+
(2 results)

機能テストでクエリをデバッグする

sfTesterDoctrineクラスは->debug()メソッドを含むようになりました。 このメソッドは現在のコンテクストで実行されたクエリについての情報を出力します。

$browser->
  get('/articles')->
  with('doctrine')->debug()
;

メソッドに数値を渡すことで直近の実行されたクエリの履歴を見ることができ、文字列を渡すことで部分列にマッチするものや正規表現にマッチするクエリだけを表示することができます。

$browser->
  get('/articles')->
  with('doctrine')->debug('/from articles/i')
;

sfFormFilterDoctrine

sfFormFilterDoctrineクラスはqueryオプションを通してDoctrine_Queryの種をまかれるようになりました(The sfFormFilterDoctrine class can now be seeded a Doctrine_Query object via the query option):

$filter = new ArticleFormFilter(array(), array(
  'query' => $table->createQuery()->select('title, body'),
));

->setTableMethod()(またはtable_methodオプション)を通して指定されたテーブルメソッドはクエリーオブジェクトを返す必要がありません。つぎはどれも有効なsfFormFilterDoctrineテーブルメソッドです:

// symfony >= 1.2 で動作します
public function getQuery()
{
  return $this->createQuery()->select('title, body');
}
 
// symfony >= 1.2 で動作します
public function filterQuery(Doctrine_Query $query)
{
  return $query->select('title, body');
}
 
// symfony >= 1.3 で動作します
public function modifyQuery(Doctrine_Query $query)
{
  $query->select('title, body');
}

フォームフィルターのカスタマイズが簡単になりました。 フィールドのフィルタリングを追加するには、必要なことはウィジェットとそれを処理するメソッドを追加することだけです。

class UserFormFilter extends BaseUserFormFilter
{
  public function configure()
  {
    $this->widgetSchema['name'] = new sfWidgetFormInputText();
    $this->validatorSchema['name'] = new sfValidatorString(array('required' => false));
  }
 
  public function addNameColumnQuery($query, $field, $value)
  {
    if (!empty($value))
    {
      $query->andWhere(sprintf('CONCAT(%s.f_name, %1$s.l_name) LIKE ?', $query->getRootAlias()), $value);
    }
  }
}

以前のバージョンでは、これを動かすためにはウィジェットをメソッドを作ることに加えてgetFields()を拡張する必要がありました。

Doctrineを設定する

Doctrineを設定するためにdoctrine.configuredoctrine.configure_connectionイベントをリスニングできます。 このことはプラグインがsfDoctrinePluginの先に有効にされている限り、プラグインからDoctrineのコンフィギュレーションを簡単にカスタマイズできることを意味します。

doctrine:generate-moduledoctrine:generate-admindoctrine:generate-admin-for-route

doctrine:generate-moduledoctrine:generate-admindoctrine:generate-admin-for-routeタスクは生成モジュールのアクション基底クラスのコンフィギュレーションを可能にする--actions-base-classオプションをとります。

マジックメソッドはのdocタグ

symfonyがDoctrineモデルに追加するゲッターとセッターのマジックメソッドはそれぞれの生成基底クラスのdocヘッダーに現れます。 IDEがコード補完をサポートする場合、これらのgetFooBar()setFooBar()メソッドがモデルオブジェクトに現れることがわかります。FooBarはキャメルケースのフィールド名です。

Webデバッグツールバー

sfWebDebugPanel::setStatus()

Webデバッグツールバーのそれぞれのパネルはタイトルの背景色に影響を及ぼすステータスを指定できるようになりました。 たとえば、sfLogger::INFOよりも優先順位が高いメッセージがロギングされる場合、logパネルのタイトルの背景色は変わります。

sfWebDebugPanelリクエストパラメーター

sfWebDebugPanelパラメーターをURLにつけ加えることでページロードで開くパネルを指定できるようになりました。 たとえば、?sfWebDebugPanel=configを追加すればconfigパネルを開くようにWebデバッグツールバーはレンダリングされます。

パネルはWebデバッグのrequest_parametersオプションにアクセスすることでリクエストパラメーターをインスペクトします:

$requestParameters = $this->webDebug->getOption('request_parameters');

パーシャル

スロットの改善

get_slot()include_slot()ヘルパーはスロットが提供されない場合返すデフォルトのスロットの内容を指定するための2番目のパラメーターを受け取ります:

<?php echo get_slot('foo', 'bar') // もし`foo`スロットが定義されていなければ 'bar'が出力されます ?>
<?php include_slot('foo', 'bar') // もし`foo`スロットが定義されていなければ 'bar'が出力されます ?>

ページャー

sfDoctrinePagersfPropelPagerメソッドはIteratorCountableインターフェイスを実装しています。

<?php if (count($pager)): ?>
  <ul>
    <?php foreach ($pager as $article): ?>
      <li><?php echo link_to($article->getTitle(), 'article_show', $article) ?></li>
    <?php endforeach; ?>
  </ul>
<?php else: ?>
  <p>No results.</p>
<?php endif; ?>

ビューキャッシュ

ビューキャッシュマネージャーはfactories.ymlでパラメーターを受け取ります。 ビュー用のキャッシュキーの生成はクラスを楽に拡張できるように異なる方法でリファクタリングされてきました。

2つのパラメーターがfactories.ymlで利用できます:

  • cache_key_use_vary_headers (デフォルト: true): キャッシュキーがVaryヘッダーの部分を含むか指定します。 実際には、varyキャッシュパラメーターで指定されるので、これはページキャッシュがHTTPヘッダーに依存するかどうかを伝えます。

  • cache_key_use_host_name (デフォルト: true): キャッシュキーがホスト名の部分を含むか指定します。 実際には、これはページキャッシュがホスト名に依存するかどうかを伝えます。

さらにキャッシュ

ビューキャッシュマネージャーは$_GETもしくは$_POSTの配列に値が存在するのかによってキャッシュを拒絶することはありません。 ロジックは現在のリクエストがcache.ymlをチェックする前のGETメソッドであることを確認するだけです。 このことは次のページがキャッシュ可能であることを意味します:

  • /js/my_compiled_javascript.js?cachebuster123
  • /users?page=3

リクエスト

getContent()

リクエストの内容はgetContent()メソッドを通してアクセスできるようになりました。

PUTDELETEパラメーター

リクエストがaplication/x-www-form-urlencodedにセットされたContent-TypeでPUTDELETE HTTPメソッドで来たばあいに、symfonyは生のボディを解析し、通常のPOSTパラメーターのようにアクセスできるパラメーターを作成します。

アクション

redirect()

sfAction:redirect()メソッド類はsymfony 1.2で導入されたurl_for()の特徴と互換を持つようになりました。

// symfony 1.2
$this->redirect(array('sf_route' => 'article_show', 'sf_subject' => $article));
 
// symfony 1.3
$this->redirect('article_show', $article);

この強化はredirectIf()redirectUnless()にも適用されました。

ヘルパー

link_to_if(), link_to_unless()

link_to_if()link_to_unless()ヘルパーはsymfony 1.2で導入されたlink_to()メソッドと互換をもつようになりました:

// symfony 1.2
<?php echo link_to_unless($foo, '@article_show?id='.$article->getId()) ?>
 
// symfony 1.3
<?php echo link_to_unless($foo, 'article_show', $article) ?>

コンテキスト

メソッドを動的にsfContextに追加するためにcontext.method_not_foundをリスニングできます。 プラグインから遅延ロードファクトリを追加する場合に便利でしょう。

class myContextListener
{
  protected
    $factory = null;
 
  public function listenForMethodNotFound(sfEvent $event)
  {
    $context = $event->getSubject();
 
    if ('getLazyLoadingFactory' == $event['method'])
    {
      if (null === $this->factory)
      {
        $this->factory = new myLazyLoadingFactory($context->getEventDispatcher());
      }
 
      $event->setReturnValue($this->factory);
 
      return true;
    }
  }
}

This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.