このチュートリアルでsymfony 1.2のための簡単に技術的な内容について紹介します。 すでにsymfony 1.0や1.1で作業をしたことがあり、symfony 1.2の新しい機能について学びたい開発者のためのチュートリアルです。
最初に、symfony 1.1がPHP 5.1、symfony 1.0がPHP 5.0で動作していたのに対してsymfony 1.2はPHP 5.2.4かそれ以降に対応していることに注意してください。
もし、symfony 1.0か1.1からアップグレードしたいのであれば、symfonyをインストールしたディレクトリにあるUPGRADEファイル(/installation/1_2/upgrade)ファイルを読んでください。 ここにsymfony 1.2にプロジェクトを安全にアップグレードするために必要とされる情報のすべてがあります。
Propel
Propelはバージョン1.3にアップグレードされました。 このバージョンではCreoleに代わりPDOがサポートされいたり、多くの新しい機能が含まれています。 新しい機能とはオブジェクトインスタンスプーリング、マスタースレーブコネクション、入れ子集合のサポート、そしてよりよい日付関連のハンドリングなどです。
databases.yml
設定ファイルはPDO構文を使うようになりました。
dev: propel: param: classname: DebugPDO all: propel: class: sfPropelDatabase param: dsn: mysql:dbname=example;host=localhost username: username password: password encoding: utf8 persistent: true pooling: true classname: PropelPDO
トランザクションAPIはわずかに変更がありました。
それは->begin
は->beginTransaction()
に、そして->rollback()
は->rollBack()
に変更されたことです。
::doSelectRS
メソッドは::doSelectStmt
に変更されました。
さらなるアップグレードの詳細についてはPropelの公式サイトにあるcomplete documentationを読んでください
Doctrine
Doctrineはsymfony 1.2の第1級市民です。 symfony 1.2では Propelプラグインと Doctrineプラグインの両方をバンドルしているということです。 全ての組み込まれた機能はPropelとDoctrineの両方で利用できます。 よりふさわしいORマッパーを自由に選んでください。
リクエスト
ブラウザからのPUT
とDELETE
リクエストをPOST
メソッドと特別なsf_method
パラメーターを追加することでシミュレーションが可能になりました。
<form action="#" method="POST"> <input type="hidden" name="sf_method" value="PUT" /> <!-- // ... --> </form>
form_tag()
ヘルパーは GET
とPOST
と異なるメソッドのために自動的にhiddenタグを生成します。
そのため、formの開始タグは次のようにform_tag()
ヘルパーを使うことで生成できます。
<?php echo form_tag('#', array('method' => 'PUT')) ?>
link_to()
ヘルパーはCSRFへの保護機能が有効になっている場合、CSRFトークンを埋め込むようになりました。
checkCSRFProtection()
メソッドを使うことでリンクがクリックされたときにトークンをチェックすることができます。
public function executeDelete($request) { $request->checkCSRFProtection(); }
トークンが存在しなかったり有効でない場合は、checkCSRFProtection()
は例外を投げます。
フォーム
フォームの入れ子
symfony1.1ではPropelでのフォームの主な制限の1つとして組み込まれたフォームからオブジェクトを自動保存することができないことでした。 symfony1.2では実装されるようになりました。 これはPropelのフォームを保存するとき、symfonyによって自動的に主となるオブジェクトと関連する入れ子になったフォームの全てをオブジェクトを保存してくれるということです。
新しいsfForm
メソッド
新しいsfForm::renderFormTag()
メソッドはform
開始タグを現在のフォームのために生成します。
また、フォームがマルチパートを必要とする場合はenctype
属性も追加しますし、メソッドがGET
またはPOST
以外の場合はhiddenタグを追加します。
<?php echo $form->renderFormTag('@article_update', array('method' => 'PUT')) ?>
sfFormPropel
クラスは関連するオブジェクトに基づくHTTPメソッドを自動的に変更するためにrenderFormTag()
を再定義します。
つまり、オブジェクトが新しければ、メソッドはPOST
でありオブジェクトがすでに存在すればメソッドはPUT
になるでしょう。
sfForm::hasErrors()
メソッドはフォームにエラーがあるはtrueを返し、そうでない場合はfalseを返します。
このメソッドはフォームに値が結びつけられていない場合はfalse
を返します。
このメソッドはテンプレートでとても役に立ちます。
<?php if ($form->hasErrors()): ?> The form has some errors you need to fix. <?php endif; ?>
sfForm::renderUsing()
メソッドのおかげで、特定のウィジットスキーマのフォーマッターを使ってレンダリング処理が行えるようになりました。
これによってテンプレートにおいて直接フォーマッターを使うことができるようになります。
// in a template, the form will be rendered using the "list" form formatter echo $form->renderUsing('list');
sfForm::renderHiddenFields()
メソッドはhiddenウィジットのためのHTMLを返します。
フォームのフィールドをテンプレート内で見えないようにしたいときに役に立ちます。
<form action="<?php echo url_for('@some_route') ?>"> <?php echo $form->renderHiddenFields() ?> <ul> <?php echo $form['name']->renderRow() ?> </ul> <input type="submit" /> </form>
sfForm::getStylesheets()
とsfForm::getJavaScripts()
メソッドはフォームのレンダリング処理に必要なスタイルシートとJavaScriptファイルを返します。
フォームの中が、またはより一般的に各ウィジット(詳しくはウィジェットの項目を確認してください)の中で上記メソッドを上書きこれらのファイルを定義することができます
テンプレート中ではinclude_javascripts_for_form()
とinclude_stylesheets_for_form()
ヘルパーを利用できます。
これら両方とも引数としてフォームオブジェクトを渡します。
<?php include_javascripts_for_form($form) ?> <?php include_stylesheets_for_form($form) ?>
sfForm
はより簡単にテンプレート内でフォームのフィールドを繰り返しやすくできるようにIterator
とCountable
インターフェースを実装しています。
<ul> <?php foreach ($form as $field): ?> <li><?php echo $field ?></li> <?php endforeach; ?> </ul>
前処理で値をクリーンアップする
オブジェクトを更新して、Propelによって値が利用される前に値をクリーニングできる前処理の方法が追加されました。
もし値のための前処理を行いたいのであれば、updateXXXColumn()
メソッドをXXXがPropelカラムのPHP名である部分のフォームに追加する必要があります。
このメソッドは 処理された値かクリーンアップされた値の配列から値をとりのぞくためにfalse
を返さなければなりません。
class UserForm extends sfFormPropel { // ... protected function updateProfilePhotoColumn($value) { // ユーザーがprofile_photoを投稿しなかった場合、 // 古い値を維持したいので複数の値から // その値を削除する if (!$value) { return false; } // 古い写真を削除する // 写真をディスクに保存する // 値を新しいファイルの名前に変更する return $filename; } }
バリデーター
sfValidatorSchemaCompare
sfValidatorSchemaCompare
定数は変更されました。
コードに変更は必要ありません。
しかしこれからは、すばらしいショートカットを使うことができます。
次の2つの例が実装例です。
// symfony 1.1 と 1.2での記述方法 $v = new sfValidatorSchemaCompare('left', sfValidatorSchemaCompare::EQUAL, 'right'); // symfony 1.2での記述方法 $v = new sfValidatorSchemaCompare('left', '==', 'right');
sfValidatorChoice
sfValidatorChoice
はsfValidatorChoiceMany
にある multiple
オプションと同じふるまいをするためにmultiple
オプションを持つようになりました。
sfValidatorPropelChoice
はsfValidatorPropelChoiceMany
にあるmultiple
オプションと同じふるまいをするためにmultiple
オプションを持つようになりました。
sfValidatorDateRange
symfony 1.2は日付の期間をバリデートするための新しいsfValidatorDateRange
バリデーターを備えています。
sfValidatorFile
sfValidatedFile
クラスはファイルを保存するときにもう少し柔軟に対応できるようになりました。
このコンストラクターは新しい引数をとることができ、ファイルを保存するときに利用するパスを渡すことができます。
それで、ファイルを保存するとき、次のようにすることができます。
これまでのように絶対パスでファイル名を渡す
$file->save(sfConfig::get('sf_uploads_dir').'/filename.pdf');
相対パスを渡す(symfonyはパスを先頭に加えることで絶対パスを作成します)
$file->save('filename.pdf');
null
を渡す。この場合ファイル名はgeneratedFilename()
メソッドによって自動的に生成されます。$file->save();
さらに、 save()
メソッドは(引数のパスに相対的な)保存されたファイルのファイル名を返すようになりました。
sfValidatedFile
オブジェクトはsfValidatorFile
バリデーターによって生成されるので、新しいpath
オプションは後者のクラスに追加されsfValidatedFile
コンストラクターにただ渡されるだけです。
$this->validatorSchema['file'] = new sfValidatorFile(array('path' => sfConfig::get('sf_uploads_dir')));
sfFormPropel
はこれらの新しい改良部分をPropelオブジェクトに関連するファイルの保存を自動化することで活用することができます。
それが新しいsaveUploadedFile()
メソッドです。
そのため、もしfile
カラムを持つPropelオブジェクトがあり、フォームクラスでfile
バリデーターを定義するときパスを渡しているならsymfonyはあなたの代わりに全ての処理を行ってくれます。
もしフォームにファイルがアップロードされていないのなら
- 何もせずにデータベースにも変更を加えません
もしファイルがアップロードされたなら
- 古いファイルを削除
- 新しいファイルを保存
file
カラムにファイル名をセット(与えられたパスへの相対)
それで、関連するアクションにおいて、ただ$this->form->save()
とするだけで自動的にオブジェクトを保存しファイルを保存します。
標準では、symfonyはハッシュと推測した拡張子を追加してユニークなファイル名を生成します。
もしファイル名を変更したいならgenerateXXXFilename()
メソッドをオブジェクト内に作成するだけです。
XXXの部分はカラムのPHP名が入ります。
このメソッドはsfValidatedFile
オブジェクトに与えられています。
public function generateFileFilename(sfValidatedFile $file) { return $this->getId().$file->getExtension($file->getOriginalExtension()); }
もちろん さきほど説明したようにupdateXXXColumn()
をこのふるまいをオーバーライドするために作成し、
あなた自身でファイルのアップロードの処理をマージすることも可能です。
sfValidatorI18nChoiceCountry
とsfValidatorI18nChoiceLanguage
symfony 1.1ではsfValidatorI18nChoiceCountry
とsfValidatorI18nChoiceLanguage
バリデーターはculture
オプションが必須でした。
このculture
はこれらのバリデーターで使われていないので、culture
オプションは廃止予定です。
後方互換性のためにまだ残っていますが、もう使う必要はありません。
メッセージに関連するrequired
とinvalid
の標準エラーコードの設定
2つの新しいメソッドがsfValidatorBase
クラスに追加され、標準時のrequired
とinvalide
エラーコードのためのメッセージを定義できるようになりました。
sfValidatorBase::setRequiredMessage('This field is required'); sfValidatorBase::setInvalidMessage('The value provided for this field is invalid');
ウィジェット(Widgets)
ウィジェットオプション
全てのウィジェットは新しいdefault
オプションを持ちます。
このオプションはウィジェットの標準の値をセットします。
$widget = new sfWidgetFormInput(array('default' => 'default value')); $widget->setDefault('default value'); echo $widget->getDefault();
ウィジェットのスキーマに標準の値をセットすることもできるようになりました。
$widget = new sfWidgetFormSchema(...); $widget->setDefaults(array('name' => 'default value')); $widget->setDefault('name', 'default value'); var_export($widget->getDefaults());
フォームの標準の値で上書きしないときこれらの標準に設定した値はそのことを考慮します
すべてのウィジェットは新しいlabel
オプションを持ちます。
このオプションは各ウィジェットにラベルを設定します。
$widget = new sfWidgetFormInput(array('label' => 'Enter your name here')); $widget->setLabel('Enter your name here'); echo $widget->getLabel();
ウィジェットのJavaScriptとスタイルシート
ウィジェットではgetJavascripts()
とgetStyleSheets()
メソッドでレンダリングする必要があるJavaScriptとスタイルシートを宣言することができます。
class MyWidget extends sfWidgetForm { public function getJavaScripts() { return array('/path/to/a/file.js'); } public function getStylesheets() { return array('/path/to/a/file.css' => 'all', '/path/to/a/file.css' => 'screen,print'); } }
getJavaScripts()
メソッドはJavaScriptファイルの配列を返さなければなりません。
getStylesheets()
メソッドはファイル名をキーとし、メディアを値とする配列を返さなければなりません。
新しいwidget
symfony 1.2には新しいwidgetが備わっています。
sfWidgetFormDateRange
sfWidgetFormFilterInput
sfWidgetFormFilterDate
sfWidgetFormI18nSelectCurrency
sfWidgetFormSelectCheckbox
sfWidgetFormChoice
ファミリー
新しいchoice
ウィジェットファミリーも追加されました。
sfWidgetFormChoice
sfWidgetFormChoiceMany
sfWidgetFormPropelChoice
sfWidgetFormPropelChoiceMany
標準で、これらのウィジェットはSelect
系のウィジェットの複製のように動作します。
しかし、それらはsfWidgetFormSelect
、sfWidgetFormSelect
、sfWidgetFormSelectRadio
そしてsfWidgetFormSelectCheckBox
ウィジットの上部にあるラッパーです。
レンダリングのためにこれらの1つを使います。
標準ウィジェットを変更するためにはいくつかのオプションを利用できます。
expanded
:- もしfalseなら、ウィジェットは
select
タグになります。 - もしtrueで
multiple
がfalseなら、ウィジェットはradio
タグのリストになります。 - もしtrueで
multiple
がtrueなら、ウィジェットはcheckbox
タグのリストになります。
- もしfalseなら、ウィジェットは
rendered_options
: ウィジェット(select
、radio
、checkbox
)を作成するとき、これはレンダリング処理されるウィジェットに渡したいオプションです。renderer_class
: 標準クラスの代わりに利用するクラスrenderer
: 直接オブジェクトを渡すこともできます(これは前述のオプションを上書きします)
オプションを利用したサンプルです。
$widget = new sfWidgetFormPropelSelect(array('model' => 'Article')); // は次と同等である $widget = new sfWidgetFormPropelChoice(array('model' => 'Article')); // ラジオボタンを使うようにレンダリングを変更する $widget->setOption('expanded', true); // 複数の選択肢を作る $widget = new sfWidgetFormPropelChoiceMany(array('model' => 'Article')); // チェックボックスリストを使うようにレンダリングを変更する $widget->setOption('expanded', true);
フォームを生成されたPropelのためにこれらの新しいウィジェットは標準で利用できます。
レスポンス
sfWebResponse::getCharset()
getCharset()
はレンスポンスの現在の文字セットを返します。
コンテントタイプの設定を変更することでこの文字セットは自動的に更新されます。
sfWebResponse::getStylesheets()
とsfWebResponse::getJavascripts()
もしsfWebResponse::ALL
を最初の引数として渡せばgetStyleSheets()
とgetJavascripts()
メソッドは現在は全てのスタイルシートとJavaScriptをポジションで指定された順番で返します。
$response = new sfWebResponse(new sfEventDispatcher()); $response->addStylesheet('foo.css'); $response->addStylesheet('bar.css', 'first'); var_export($response->getStylesheets()); // 出力 array( 'bar.css' => array(), 'foo.css' => array(), )
sfWebResponse::ALL
はポジションの引数のための標準の値でもあります。
PrototypeとScriptaculous
symfony 1.2においてバンドルされていたPrototypeとScriptaculousライブラリとヘルパー(JavascriptHelper
)はコアプラグインに移動しました。
コアプラグインは本物のプラグインのようにふるまいますが、symfonyプラットフォームによって操作されます。
(コア)プラグインなので、新しいsfProtoculousPlugin
(PrototypeとScriptaculousの組み合わせの名前で非公式でよく使われる)のJavaScriptとCSSファイルが作成され、これらは本当のプラグインアセットとして動作します。
これらは (1.0や1.1のときに配置されていた)web/sf
ディレクトリではなくweb/sfProtoculousPlugin
ディレクトリに配置されることになります。
prototype_web_dir
設定はその新しいディレクトリ(web/sfProtoculousPlugin)を指し示すようにもなります。
さらに、いろいろなJSフレームワークによって利用される基本的なJavascriptヘルパーがコア部分にJavascriptBaseHelper
として抽出されます。
新しい追加機能として、javascript_tag()
はslot()
のように動作するようになります。次のような使い方ができます。
<?php javascript_tag() ?> alert('All is good') <?php end_javascript_tag() ?>
テスト
sfBrowser::info()
多くの機能テストをモジュールのために書くとき、何が行われているかについての視覚的な情報が役に立つことがあります。
symfony 1.2ではinfo()
メソッドがあなたのテストをカテゴライズするのに役立つテキストを出力します。
$browser-> info('First scenario')-> // ... some tests info('Second scenario')-> // ... some more tests ;
デバッキングテスト
機能テストで問題が発生するとき、ブラウザーに送信されたHTMLは原因を診断するために役に立ちます。 symfony 1.2では流暢なインターフェーススタイルを邪魔することなく生成されたHTMLを表示することができます。
$browser-> get('/a_uri_with_an_error')-> with('response')->debug()-> // some tests that won't be executed ;
debug()
メソッドはレスポンスヘッダーとコンテンツを出力し、ブラウザのフローを遮ります。
テスター
sfTestFunctionalBase
クラスは実際のテストをsfTester
クラスに委任するようになりました。
symfony 1.2はいくつかの組み込みテスタークラスがあります。
request
:sfTesterRequest
response
:sfTesterResponse
user
:sfTesterUser
view_cache
:sfTesterViewCache
全ての古いテストブラウザのメソッドはテスタークラスのメソッドに移動されました:
メソッドの名前 | テスタークラス | 新しいメソッドの名前 |
---|---|---|
isRequestParameter |
sfTesterRequest |
isParameter |
isRequestFormat |
sfTesterRequest |
isFormat |
isStatusCode |
sfTesterResponse |
isStatusCode |
responseContains |
sfTesterResponse |
contains |
isResponseHeader |
sfTesterResponse |
isHeader |
checkResponseElement |
sfTesterResponse |
checkElement |
isUserCulture |
sfTesterUser |
isCulture |
isCached |
sfTesterViewCache |
isCached |
isUriCached |
sfTesterViewCache |
isUriCached |
テスタークラスも新しいメソッドが用意されました。
テスタークラス | 新しいメソッドの名前 |
---|---|
sfTesterRequest |
hasCookie |
sfTesterRequest |
isCookie |
sfTesterRequest |
isMethod |
sfTesterUser |
isAuthenticated |
sfTesterUser |
hasCredential |
sfTesterUser |
isAttribute |
sfTesterUser |
isFlash |
以下が新しいテスターの使い方です。
$browser-> get('/')-> with('request')->isParameter('module', 'foo')-> with('request')->isParameter('module', 'bar') ;
with()
メソッドを呼び出すことで呼び出し可能なメソッドにあるテスターオブジェクトを返します。
もし、複数のメソッドをテスターオブジェクトで呼び出したいなら、それらをblock
内におくことができます。
$browser-> get('/')-> with('request')->begin()-> isParameter('module', 'foo')-> isParameter('module', 'bar')-> isMethod('get')-> isFormat('html')-> end()-> with('response')->begin()-> isStatusCode(200)-> checkElement('body', 'foo')-> isHeader('Content-Type', 'text/html; charset: UTF-8')-> isRedirected(false)-> end() ;
sfTester
を継承するクラスを作成し登録することによって独自のテスターを追加することができます。
$browser->setTester('my_tester', 'myTesterClassName');
既存のテスタークラスも標準のクラス名を上書きすることで拡張することができます。
$browser->setTester('request', 'myTesterRequest');
フォームがあるページのテストを改善するために、select()
とdeselect()
メソッドをテストブラウザに追加しました。
現在はチェックボックスの選択/非選択とラジオボタンの選択処理をサポートしており、これは同じname
のラジオボタンが非選択になる原因かもしれません。
$browser-> select('aRadioId')-> select('aCheckboxId')-> deselect('anotherCheckbox');
Cookie
クッキーは sfBrowser
やsfTestBrowser
クラスにおいてもサポートされるようになりました。
クッキーを sfBrowser
クラスにあるsetCookie()
、removeCokie()
そしてclearCookies()
メソッドを使うことでリクエストとリクエストの間で扱うことができます。
$b-> setCookie('foo', 'bar')-> removeCookie('bar')-> get('/')-> // ... clearCookies()-> get('/')-> // ...
また、sfTesterRequest
クラスからhasCookie()
とisCookie()
メソッドでCookieをテストすることができます。
$b-> get('/')-> with('request')->begin()-> hasCookie('foo')-> hasCookie('foobar', false)-> isCookie('foo', 'bar')-> isCookie('foo', '/a/')-> isCookie('foo', '/!z/')-> end() ;
hasCookie()
メソッドは第2引数でクッキーがセットされてない状態をテストするための真偽値をとります。
isCookie()
メソッドの第2引数はcheckElementResponse
メソッドの第2引数のようにふるまいます。
それは文字列、正規表現もしくは否定正規表現だったりします。
ブラウザークラスは自動的に各Cookieのexpire
値ごとにCookieを消します。
リクエスト
リクエストテスターからisMethod()
メソッドを使ってあなたの機能テストのリクエストに使われるHTTPメソッドをテストすることもできます。
$b-> setField('login', 'johndoe')-> click('Submit')-> with('request')->isMethod('post');
リンク
リンクになっているクリックやボタンをシミュレーションするとき、click()
メソッドという名前を使います。
しかし、同じ名前で2つの異なるリンクやボタンを差別化することができません。
symfony 1.2では click()
メソッドではオプションを第3引数に渡します。
position
というオプションをクリッックしたいしたいリンクを変更するときに渡します。
$b-> click('/', array(), array('position' => 1))-> // ... ;
標準で、symfonyはページにある項目の最初のリンクをクリックします。
method
オプションでクリックしたいリンクやフォームのメソッドを変更することもできます。
$b-> click('/delete', array(), array('method' => 'delete'))-> // ... ;
これはリンクがJavaScriptで動的に生成されるフォームで変換される場合に役立ちます。
_with_csrt
オプションを渡すことでlink_to()
ヘルパーによってCSRFトークンの生成をシミュレートすることもできます。
$b-> click('/delete', array(), array('method' => 'delete', '_with_csrf' => true))-> // ... call('/delete', 'delete', array('_with_csrf' => true))-> // ... ;
フォーム
新しいフォームフレームワークを使うなら、投稿されたフォームから生成されたエラーをテストすることができるようになりました。
$browser-> click('save', array(...))-> with('form')->begin()-> hasErrors()-> isError('name', 'Required.')-> isError('name', '/Required/')-> isError('name', '!/Invalid/')-> isError('name')-> isError('name', 1)-> end() ;
また、debug()
メソッドでフォームをデバッグすることもできます。
$browser-> click('save', array(...))-> with('form')->debug()-> // some tests that won't be executed ;
もしエラーがあればサブミットされた値と全てのエラーを出力します。
Propel
Propelプラグインにはpropelテスターが附属しています。このテスターは標準では登録されていません。
$browser->setTester('propel', 'sfTesterPropel');
このテスターはPropelモデルをテストするためのcheck()
メソッドを提供します:
$browser-> post('...', array(...))-> with('propel')->begin()-> check('Article', array(), 3)-> check('Article', array('title' => 'new title'))-> check('Article', array('title' => 'new title'))-> check('Article', array('title' => 'new%'))-> check('Article', array('title' => '!new%'), 2)-> check('Article', array('title' => 'title'), false)-> check('Article', array('title' => '!title'))-> end() ;
最初の引数はモデル名になり、第2引数はCriteria
オブジェクトか条件を表した配列になります。
そして第3引数は次のどれかでなければなりません。
true
:Criteria
が返す最低でも1つのオブジェクトをチェックするfalse
:Criteria
がオブジェクトを返さないことをチェックする- 返されるオブジェクトの数をチェックするための数値
カバレッジ
実行したテストのコードカバレッジを出力するための新しいtest:coverage
タスクが用意されました。
$ ./symfony test:coverage test/unit/model/ArticleTest.php lib/model/Article.php
最初の引数はファイルかテストのディレクトリです。第2引数はあなたがカバーしたいファイルかディレクトリになります。
もし、どの行がカバーされていないかを知りたいなら、次のように--detailed
オプションを追加するだけです。
./symfony test:coverage --detailed test/unit/model/ArticleTest.php lib/model/Article.php
ロガー
symfony 1.2では新しいロガーが組み込まれました。
それがsfVarLogger
です。
このロガークラスは後で利用するために全てのメッセージを配列でロギングします。
ログをとって、それらを次のように使うことができるようになります。
$log = new sfVarLogger(); $log->log('foo'); var_export($log->getLogs()); // outputs array( 0 => array( 'priority' => 6, 'priority_name' => 'info', 'time' => 1219385295, 'message' => 'foo', 'type' => 'sfOther', 'debug_stack' => array() ) )
各ログはpriority
、priority_name
、time
、message
、type
そしてdebug_stack
というキーを持つ連想配列です。
debug_stack
属性はxdebug_logging
オプションがtrue
にセットされているときだけセットされます。
オプションがセットされているときはxdebugのスタックトレースを配列をして保持しています。
sfVarLogger
はまたsfWebDebugLogger
クラスの基礎となるクラスでもあります。
そのため、sfWebDebugLogger
のxdebugLogging
オプションはxdebug_logging
に名前が変更されました。
Webデバッグツールバー
Webデバッグツールバーはカスタマイズができるようになりました。ツールバーはパネルで構成されています。
パネルはsfWebDebugPanel
を拡張したオブジェクトであり、ツールバー上に表示するために必要とされる情報を
提供してくれます。
標準では、次のようなパネルが自動的に登録されています。
名前 | クラス名 |
---|---|
symfony_version | sfWebDebugPanelSymfonyVersion |
cache | sfWebDebugPanelCache |
config | sfWebDebugPanelConfig |
logs | sfWebDebugPanelLogs |
time | sfWebDebugPanelTimer |
memory | sfWebDebugPanelMemory |
db | sfWebDebugPanelPropel |
ウェブデバッグツールバーをdebug.web.load_panels
イベントリスナーを利用することでカスタマイズできます。
このリスナーで追加された新しいパネルを追加したとき、すでに存在するパネルを削除したときや別のものに置き換えることができます。
sfWebDebugPanelLogs
パネルはdebug.web.filter_logs
イベントを通知することで表示されるログをフィルター処理します。
たとえば、sfWebDebugPanelPropel
とsfWebDebugPanelTimer
は全てのPropelに関連するログやログパネルからタイマーログを取り除くためにこのイベントに接続します。
ウェブデバッグツールバーに表示される全体の時間は$_SERVER['REQUEST_TIME']
(以前はsfConfig::get('sf_time_start')
で計算していましたが、もやはこれは存在しません)で計算しています。
これは表示される時間はsymfony1.0や1.1よりもより長くなっていることを意味します。
タスク
取り込まれているPhingタスクが失敗するなら、Phingに依存しているPropelタスクははっきりとしたエラーメッセージを出力します。
CLIタスクの中にはアプリケーション名を引数として必要としているものがあります。 なぜならそれらはデータベースに接続する必要があるからです。 アプリケーション上でカスタマイズされる設定ファイルが必要なため私たちはアプリケーションが必要なのです。 そして全てのsymfonyの設定システムはアプリケーションレベルが基礎となっています。
これらのタスクにとって、引数はオプションである"application"オプションになってとりのぞかれました。
もし、"application"オプションを提供しないならsymfonyはプロジェクトのdatabases.yml
ファイルからデータベース設定を取得してくるようになりました。
次のタスクの用法はこれらに従って変更されました。
propel:build-all-load
propel:data-dump
propel:data-load
note
これはsfDatabaseManager
が今ではプロジェクト設定やアプリケーション設定を取得するようになったので可能になりました。
興味深いこととで、sfDatabaseConfigHandler
は今では静的か動的な設定ファイルの配列に基づく設定を返すから動作するのです(exeute()
とevaluate()
メソッドをごらんください)
デバッグのために、propel;build-model
、propel:build-all
そしてpropel:build-all-load
タスクは--trace
オプションを指定すれば生成されるスキーマをとりのぞきません。
propel:insert-sql
propel:insert-sql
タスクは全てのデータをデータベースからとりのぞきます。
情報を破壊するので、タスクの実行前にユーザーにたずねるようになりました。
propel:build-all
とpropel:build-all-load
タスクもpropel:insert-sql
タスクと同じことがあてはまります。
もし、これらのタスクをバッチ処理で使いたいなら確認のための質問を避けたいでしょう。
そのときはno-confirmation
オプションを渡してください:
$ php symfony propel:insert-sql --no-confirmation
symfony 1.2より前では、propel:insert-sql
タスクはpropel.ini
からのデータベースの情報を読み込むことしかしませんでした。
symfony 1.2ではdatabases.yml
から読み込むことができるようになりました。
そのため、モデルに複数の異なる接続先を設定したいならこのタスクはそれらを考慮するようになりました。
この新しい機能のおかげで、もし指定した接続先からのSQLだけを読み込みたい場合に--connection
オプションを指定することができるようになりました:
$ php symfony propel:insert-sql --connection=propel
また--env
と--application
オプションも次のように特定の設定を選択するために使うことができます。
$ php symfony propel:insert-sql --env=prod --application=frontend
タスクのために利用可能な新しいメソッド
sfTask
基底クラスはタスクで利用できる3つの新しいメソッドを提供するようになりました。
logBlock()
: スタイル化されたブロックでメッセージをログします(標準のスタイルはINFO、COMMENT、ERRORです)ask()
: ユーザーに質問を行い回答を返します。askConfirmation()
: 確認をユーザーに行い、ユーザーが確認すればtrueをそうでなければfalseを返します。
propel:generate-module
propel:generate-crut
はpropel:generate-module
に名前が変更されました。
古いタスク名はエイリアスとしてまだ利用することができます。
propel:generate-module
タスクのnon-atomic-actions
オプションはとりのぞかれ次のような新しいオプションが追加されました。
- singular: The singular name for the actions and templates
- plural: The plural name for the actions and templates
- route-prefix: The route prefix to use
- with-propel-route: Whether the related routes are Propel aware
propel:generate-module-for-route
新しいpropel:generate-module-for-route
タスクはルーティングの定義に基づくモジュールを作成します。
php symfony propel:generate-module-for-route frontend articles
app:routes
いまではsymfonyは(以下のような)ルーティングを自動生成でき、app:routes
タスクは現在のアプリケーションに設定されているルーティングのリストを表示します:
php symfony app:routes frontend
もしルーティングの内容を詳しく知りたいなら、次のようにルート名を追加するだけです。
php symfony app:routes frontend articles_update
plugin:install-assets
通常プラグインはタスクでインストールされるとき正しくコアプラグインがそうであるようにwebディレクトリにシンボリックリンクが作成されます。
これと同じことを手動で行うためには以下のようにします。
symfony plugin:publish-assets --only-core
目標はプロジェクトの生成とアップグレードタスクがあなたに代わってこれを行うことです。
ルーティング
ルーティングのオプション
ルーティングタスクは2つのオプションをとります。
generate_shortest_url
: 可能なかぎり最も短いURLを生成することができるかどうかextra_parameters_as_query_string
: クエリストリングとして外部パラメータを生成するかどうか
標準では、symfony 1.0、1.1と互換性を保つためにfactories.yml
においてfalse
がセットされています。
ルーティングの基礎部分でこれらのオプションの有効無効を設定することもできます。
articles: url: /articles/:page param: { module: article, action: list, page: 1 } options: { generate_shortest_url: true }
できるだけ最短のURLを生成しようとするので、もし、page
の値として1
を渡すなら、生成されるURLは/articles
になるでしょう:
echo url_for('@articles?page=1'); // /articles // would have been /articles/1 in symfony 1.1 echo url_for('@articles?page=2'); // /articles/2
extra_parameters_as_query_string
の例は以下のようになります。
articles: url: /articles options: { extra_parameters_as_query_string: true }
ルーティングは外部パラメータを受け取り、クエリストリングとしてそれらを追加します。
echo url_for('@articles?page=1'); // /articles?page=1 // would not have matched the route in symfony 1.1 echo url_for('@articles?page=2'); // /articles?page=2
sfRoute
sfPatternRouting
クラスはフラットな連想配列の代わりにsfRoute
オブジェクトの配列でルーティングを保持しています。
標準では、symfonyは組み込みのsfRoute
オブジェクトを使います。
しかし次のように特定のclass
エンティティをrouting.yml
設定ファイルで変更することができます。
foo_bar: url: /foo/:bar class: myRoute param: { module: foo, action: bar }
全てのルーティングのロジックはsfRoute
クラスに含まれています。
これはあなた自身で用意したもので解析ロジックと生成ロジックを上書きすることができるということです。
tip
より簡単に標準の挙動をカスタマイズできるようにsfRoute
クラスは古いsfPatternRougint
クラスよりさらにモジュール化されました。
"コンパイレーション"フェーズはより小さなメソッドにリファクタリングされ、コードはよりシンプルになり、"本当の"トークナイザーに基づいています。
PHPコードであなたのルーティングに接続するなら、sfRoute
インスタンスをconnect()
、preprendRoute()
、appendRoute()
そしてinsertRouteBefore()
メソッドの第2引数として渡さなければなりません:
$route = new myRoute('/foo/:bar', array('module' => 'foo', 'action' => 'bar')); $routing->connect('foo_bar', $route);
リクエストがあった場合、一致しているルーティングオブジェクトはリクエストの属性として保存され、getRoute()
メソッドをとおしてアクションから取得することができます。
public function executeIndex() { $route = $this->getRoute(); }
sfRoute
コンストラクターは各ルーティングをカスタマイズできるようにその最後の引数としてオプションの配列をとります。
routing.yml
設定ファイルで、options
キーを次のように使います。
article: url: /article/:id-:slug options: { segment_separators: [/, ., -] }
sfRequestRoute
symfonyは別の組み込みルーティングであるsfRequestRoute
を持っており、これによってHTTPメソッドをあなたのルーティングに強制することができます。
article: url: /article/:id requirements: { sf_method: get } class: sfRequestRoute
もし、sf_method
を必要とせず指定しなければ、symfonyはget
かhead
リクエストを強制します。
sfRouting
のparse()
メソッドが第2引数としてコンテキストをとるため可能になっています。
リクエストがルーティングを呼び出すとき、次のようなコンテキストを渡します。
method
: HTTPメソッド名format
: リクエストのフォーマットhost
: ホスト名is_secure
: リクエストがHTTPSで呼び出されたかどうかrequest_uri
: 完全なリクエストURIprefix
: 生成されたルーティングに付け加えられるプレフィックス
前述のルーティング設定で、article
へのルーティングはHTTPメソッドがget
の場合のみ一致します。
同じurl
を異なるメソッドを必要とするようにルーティングを設定するなら、次のようにルーティングを生成するときsf_method
パラメーターを渡すことができます。
<?php echo link_to('Great article', '@article?id=1&sf_method=get')) ?>
sfObjectRoute
symfony 1.2 はsfRequestRoute
を継承する別のルーティングクラスであるsfObjectRoute
を実装しています。
sfObjectRoute
はPHPオブジェクトにルーティングを結びつけます。
sfObjectRoute
はオブジェクトやオブジェクトの集まりやルーティングに関連するコレクションを取得するためのPHPのクラスにメソッドを呼び出せるようにしたりします。
article: url: /article/:id class: sfObjectRoute options: { model: Article, type: object, method: getById }
URLがルーティングに一致するとき、sfObjectRoute::getObject()
メソッドで、Article::getById()
メソッドによって関連する呼び出されるオブジェクトを取得することができます。
同じことがオブジェクトの集まりにもあてはまります。
articles: url: /articles/newest class: sfObjectRoute options: { model: Article, type: list, method: getNewest }
sfPropelRoute
sfPropelRoute
はsfObjectRoute
をPropelモデルのルーティングに結びつけるために拡張されます。
アクションにおいて、sfObjectRoute::getObject()
やsfObjectRoute::getObjects()
メソッドを利用することで関連するオブジェクトやオブジェクトの集まりを取得することができます。
public function executeList($request) { $this->articles = $this->getRoute()->getObjects(); } public function executeShow($request) { $this->article = $this->getRoute()->getObject(); }
ここにArticle
Propelオブジェクトのための例があります。
article: url: /article/:id param: { module: article, action: show } class: sfPropelRoute options: { model: Article, type: object } articles: url: /articles param: { module: article, action: list } class: sfPropelRoute options: { model: Article, type: list, method: getPublishedArticleCriteria }
メソッドが定義されていないのであれば、sfPropelRoute
は利用できるルーティングの変数に基づいてCriteria
オブジェクトを構築することでオブジェクトを取得します。
sfPropelRoute
にはsfRoute
を上回る2つの主な利点があります:
リクエストがありルーティングがURLに一致するとき、一致する
sfPropelRoute
オブジェクトはアクションにて利用することができ、関連するArticle
オブジェクトはgetObject()
メソッドを呼ぶことで利用することができます。 さらに、オブジェクトがデータベースに存在しないなら、自動的に404エラーページにリダイレクトします。 これはアクションでの決まりきった指示を減らすことができるということです。このルーティングへのリンクを作成するとき、新しい
url_for()
を使うことができ、次のようにArticleオブジェクトに直接引数を渡すことができます:<?php echo url_for('article', $article) ?>
その他のパラメーターを渡すなら(例えばHTTPメソッドを強制したいような場合)、次のように配列を使うことができます。
<?php echo url_for('article', array('sf_subject' => $article, 'sf_method' => 'get')) ?>
もちろん、次のように完全なパラメーターもまだ利用することができます。
<?php echo url_for('article', array('id' => $article->getId(), 'slug' => $article->getSlug())) ?>
もしくは次のように内部URLを使うこともできます。
<?php echo url_for('@article?id='.$article->getId().'&slug='.$article->getSlug()) ?>
sfPropelRoute
はArticleオブジェクトを自動的にパラメーターの配列に変換します。
sfPropelRoute
はプライマリキーだけでは動作しません。
いろいろなカラムを用いて動作させることができます。
次の例では、slug
カラムをルーティングパターンに追加することができます。
article: url: /article/:id/:slug param: { module: article, action: show } class: sfPropelRoute options: { model: Article, type: object }
しかし、データベースに存在しない情報をパターンに含めたい場合もあるでしょう。
このような場合、method
オプションに渡すことができます。
post: url: /post/:id/:year/:month/:day/:slug param: { module: article, action: show } class: sfPropelRoute options: { model: Article, type: object, method: getObjectForRoute }
getObjectForRoute()
は最初の引数としてパラメータの配列を受け取りArticle
オブジェクトを返さなければなりません。
class ArticlePeer extends BaseArticlePeer { static public function getObjectForRoute($parameters) { $criteria = new Criteria(); $criteria->add(self::ID, $parameters['id']); return self::doSelectOne($criteria); } }
sfPropelRoute
はパラメーターを解析されるルートを上書きするためのsetListCriteria()
メソッドも提供します。
ルーティングによって返されるオブジェクトを洗練させたいときに特に役立ちます。
たとえば、次のように他のパラメーターに基づく検索などです:
public function executeList($request) { $this->filters = new ArticleFormFilter(); if ($request->isMethod('post')) { $this->filters->bind($request->getParameter('article_filters')); if ($this->filters->isValid()) { $this->getRoute()->setListCriteria($this->filters->getCriteria()); } } $this->articles = $this->getRoute()->getObjects(); }
sfRouteCollection
、sfObjectRouteCollection
そして sfPropelRouteCollection
symfonyは"collection"ルートクラスも実装しています。
これらのクラス(sfRouteCollection
、sfObjectRouteCollection
、sfPropelRouteCollection
)は定義に基づいた標準的なルーティングを作成します。
articles: class: sfPropelRouteCollection options: { model: Article, module: article }
標準では、このルーティングは以下の7つのルーティングを生成します:
- list:
articles GET /articles.:sf_format
- new:
articles_new GET /articles/new.:sf_format
- create:
articles_create POST /articles.:sf_format
- edit:
articles_edit GET /articles/:id/edit.:sf_format
- update:
articles_update PUT /articles/:id.:sf_format
- delete:
articles_delete DELETE /articles/:id.:sf_format
複数のオプションで生成されるルーティングをカスタマイズすることができます:
- model: モデルクラス名を指定
- actions: (上記の7個のリストから)生成されるアクションのリストを指定
- module: モジュール名
- prefix_path: 各ルーティングのために追加するプレフィックス
- column: プライマリキーとするカラム名(標準では
id
) - with_show: showメソッドを追加するかどうか
- segment_names:
new
とedit
のためのセグメント名 - model_methods: オブジェクトのコレクションを取得するために使うメソッド
- requirements: 標準の必須条件(標準では
id
は\d+
を要求します) - route_class: 利用するためのルートクラス
(標準では
sfObjectRoute
のためにはsfObjectRouteCollection
sfPropelRouteCollection
のためにはsfPropelRoute
を利用) - collection_actions: コレクションアクションとして追加するためのアクションのリスト
- object_actions: オブジェクトアクションとして追加するためのアクションのリスト
ここにオプションを指定した場合の別の例があります。
articles: class: sfPropelRouteCollection options: model: Article module: article prefix_path: /foo methods: [ list, edit, update ] segment_names: { list: nouveau, edit: edition } collection_actions: { filter: post } object_actions: { publish: put }
URLヘルパー
link_to()
とurl_for()
もし、POST
、PUT
またはDELETE
HTTPメソッドでサブミットされなければならないリソースへのリンクを作成したいとき、link_to()
ヘルパーでmethod
オプションを渡すことでリンクをフォームに変換することができます。
<?php echo link_to('@article_delete?id=1', array('method' => 'delete')) ?>
POST
、DELETE
そしてPUT
メソッドのために、settings.yml
でCSRFの保護機能が有効になっているならばlink_to()
ヘルパーはCSRFトークンも埋め込みます。
古いpost
オプションはまだ有効ですが廃止される予定です。
// 次は廃止される予定です <?php echo link_to('@some_route', array('post' => true)) ?> // 次で同じ実装になります <?php echo link_to('@some_route', array('method' => 'post')) ?>
ulf_for()
とlink_to()
ヘルパーは新しい特徴をサポートするようになりました。
内部URIの代わりに、ルーティング名とパラメーターの配列もとることができます。
echo url_for('@article', array('id' => 1)); echo link_to('Link to article', '@article', array('id' => 1));
何も変更を加えなくてもこれまでの設定は動作します。
コンフィギュレーション
symfony 1.2より前は、全てのプラグインはplugins
ディレクトリにインストールされていました。
そして、全ての組み込みプラグインは自動的に読み込まれていました。
symfony 1.2では、あなたのプロジェクト内で利用したいプラグインを有効にする必要があります。
ProjectConfiguration
クラスでこれを行うことができます。
Doctrineプラグインを有効にし、Propelプラグインを無効にする方法は次のとおりです:
public function setup() { $this->enablePlugins('sfDoctrinePlugin'); $this->disablePlugins('sfPropelPlugin'); }
複数のプラグインを一度に追加する場合はプラグイン名の配列を渡します:
public function setup() { $this->enablePlugins(array('sfDoctrinePlugin', 'sfGuardPlugin')); }
setPlugins
メソッドを用いることでプラグインの読み込まれる順番を変更することができます:
[php] public function setup() { $this->setPlugins(array('sfDoctrinePlugin', 'sfCompat10Plugin')); }
1.0と互換性のあるプラグインを有効にするためには、設定で次のように有効にする必要があります。
public function setup() { $this->enablePlugins('sfCompat10Plugin'); }
標準では、symfonyはPropelプラグインだけが有効です。
全てのインストールしたプラグインも有効にすることができます。
public function setup() { $this->enableAllPluginsExcept('sfDoctrinePlugin'); }
上の例のようにしてDoctrineプラグイン以外の全てのプラグインを有効にすることができます。 1.0または.1.1からアップグレードする場合は、この行によってsymfony 1.0と1.1のときのようにsymfonyを動作させることができます。
プラグインのコンフィグレーション
プラグインにはプラグインを設定するクラスのためオプションが存在します。
これらのプラグイン設定クラスはプラグインのためにオートローディングを設定し、sfProjectConfiguration
でインストールされています。
symfony 1.2タスクはプラグインクラスが使用するアプリケーション名をもはや必要としません。
プラグインはcommand.*
イベントに接続することで以前はできなかったことができるようになりました。
フィルター
symfonyはモデルに基づくフィルター(検索フォーム)をpropel:build-filters
タスクで生成することができるようになりました。:
$ php symfony propel:build-filters
このタスクは標準ではlib/filter/
ディレクトリにフィルター(検索フォーム)クラスを生成します。
Article
モデルをフィルタリング処理するためには、以下のようにアクションでコードを書く必要があります。
$this->filters = new ArticleFormFilter(); if ($request->isMethod('post')) { $this->filters->bind($request->getParameter('article_filters')); if ($this->filters->isValid()) { $this->articles = ArticlePeer::doSelect($this->filters->getCriteria()); } }
そして、以下が関連するテンプレートのコードです:
<form action="<?php echo url_for('@articles_filter') ?>" method="post"> <table> <?php echo $filters ?> <tr> <td colspan="2"> <a href="<?php echo url_for('@articles') ?>">Reset</a> <input type="submit" value="Filter" /> </td> </tr> </table> </form>
もし、永続的にリクエスト間でフィルターを保持したいなら、以下のようなちょっとした動作例のように行います:
public function executeList($request) { $this->filters = new ArticleFormFilter($this->getUser()->getAttribute('article_filters')); if ($request->isMethod('post')) { $this->filters->bind($request->getParameter('article_filters')); if ($this->filters->isValid()) { $this->getUser()->setAttribute('article_filters', $this->filters->getValues()); } } $criteria = $this->filters->buildCriteria($this->getUser()->getAttribute('article_filters')); $this->articles = ArticlePeer::doSelect($criteria); }
テンプレートの例外処理
キャッチできないあらゆる発生した例外をレンダリング処理するとき、symfonyは現在のリクエストフォーマットを考慮するようになりました。
プロジェクトまたはアプリケーションのconfig/error
ディレクトリにテンプレートを追加することで各フォーマットの出力をカスタマイズできます。
たとえば、XMLリクエストで発生したキャッチできない例外はアプリケーションがデバッグモード時はconfig/error/exception.xml.php
を、デバッグモードでない場合はconfig/error/error.xml.php
をレンダリング処理します。
プロジェクトディレクトリ内にカスタマイズした500エラーテンプレートを用意していれば、それを新しいディレクトリに手動で移動する必要があります。
- symfony 1.1 では
config/error500.php
からconfig/error/error.html.php
に - symfony 1.0 では
web/errors/error500.php
からconfig/error/error/html/php
に
ちょっとした改善
symfony 1.2ではあちらこちらで多くの改善がなされています。ここにそのいくつかを紹介します。
アクション
アクションでは、generateUrl()
を呼ぶことで直接ルーティングオブジェクトを使うことでURLを生成することができるようになります。
public function executeIndex() { $this->redirect($this->generateUrl('homepage')); }
generateUrl()
メソッドにはルーティング名、パラメーターの配列、絶対的URLを生成するかどうかをコンストラクターの引数として渡すことができます。
標準で、redirectIf()
やredirectUnless()
メソッドをアクションの中で使うとき、symfonyはHTTPレスポンスのステータスを自動的に302に変更します。
これらの2つのメソッドは追加のおpションを持つようになり、この標準のステータスコードを変更できるようになりました。
$this->redirectIf($condition, '@homepage', 301); $this->redirectUnless($condition, '@homepage', 301);
この機能はすでにredirect()
メソッドにおいて実装されています。
YAML
YAMLパーサーはキーのマージを完全にサポートしました(サンプルについてはhttp://yaml.org/type/merge.htmlをごらんください)。
$yaml = new sfYamlParser(); var_export($yaml->parse(<<<EOF default_param: &default_param datasource: propel phptype: mysql hostspec: localhost database: db username: user password: pass param: <<: *default_param username: myuser password: mypass EOF )); // 出力 array( 'default_param' => array( 'datasource' => 'propel', 'phptype' => 'mysql', 'hostspec' => 'localhost', 'database' => 'db', 'username' => 'user', 'password' => 'pass', ) 'param' => array( 'datasource' => 'propel', 'phptype' => 'mysql', 'hostspec' => 'localhost', 'database' => 'db', 'username' => 'myuser', 'password' => 'mypass', ) )
sfParameterHolder
sfParameterHolder
のhas()
メソッドはよりその本来の正しい動作になるように変更されました。
もし値がnull
だった場合はtrue
を返すようになりました:
$ph = new sfParameterHolder(); $ph->set('foo', 'bar'); $ph->set('bar', null); $ph->has('foo') === true; $ph->has('bar') === true; // symfony 1.0もしくは1.1ではfalseを返す
sfparameterHolder::has()
メソッドは多くのコアクラスの中でhasParameter()
やhasAttribute()
メソッドで利用されています。
image_tag()
ヘルパー
symfony 1.0と1.1では image_tag
ヘルパーはファイル名からimgタグのalt
属性を生成しています。
これからはsf_compat_10
が有効になっているときにだけこのように動作します。
これからは(x)htmlバリデーターが使っているセットされていないalt属性を簡単に見つけることができます。
さらに、新しいalt_title
オプションによってaltをセットし、タイトル属性を同じ値にすることができます。
これはクロスブラウザーでのツールチップとして利用できます。
ビューコンフィグレーション
symfony 1.2では、module.yml
でpartial_view_class
を設定することでパーシャルを処理するために使用されるビュークラスを変更することができるようになりました。
このクラスはsfPartialView
を拡張したものでなければなりません。
同じことがview_class
設定でも行えます。
symfonyは自動的にPartialView
をpartial_view_class
の値に適用しようとします。
# module.yml all: partial_view_class: my
ファクトリ
sfViewCacheManager
クラスはfactories.yml
で設定できるようになりました。
view_cache_manager: class: sfViewCacheManager
ビュー
標準のsf_cache_namespace_callable
設定でsfViewCacheManager::generateCacheKey()
を上書きすることができます。
symfony1.2では、collableは追加の引数のビュークラスインスタンスで呼び出されるようになりました。
イベント
symfony 1.2には新しいイベント機能が実装されています。
user.change_authentication
: ユーザーの認証ステータスが変更されたときに通知します。 このイベントは変更が発生したあとに引数としてauthenticated
フラグをとることができます。debug.web.load_panels
(例. ウェブデバッグツールバーパラグラフ)debug.web.filter_logs
(例. ウェブデバッグツールバーパラグラフ)
I18N
内部的に、sfCulterUnfo
クラスはこれらかはSingletonとしてのみ利用できるようになります。
getInstance()
メソッドをバイパスすることが可能で、新しいオブジェクトを直接インスタンス化することができるとしても廃止される予定です。
Singletonとして利用するために、1つのリクエストごとに1つのカルチャーについての情報をインスタンス化するためパフォーマンスは向上し、設定クラスの中でカルチャーをグローバルに上書きすることができるということです。
sfCulterInfo::getCountries()
とsfCulterInfo::getCurrencies()
そしてsfCultureInfo::getLanguages()
メソッドは
戻り値を制限するためのオプションの引数をとることができるようになりました。
// will only return the FR and ES countries in english $countries = sfCultureInfo::getInstance('en')->getCountries(array('FR', 'ES'));
sfCulterInfo::getCurrencies()
メソッドは通貨名の配列を返します。
以前のバージョンのsymfonyでは、通貨記号と名前の配列を返していました。
以前のような動作をさせるためには、次のように第2引数にtrue
を渡すだけです。
$currencies = sfCultureInfo::getInstance('en')->getCurrencies(null, true);
1つだけの国、言語、通貨の翻訳を取得するために、getCountry()
、getCurrency()
、getLanguage()
メソッドをsfCultureInfo
クラスから使うことができるようになりました。
インクルードパスの管理
symfony 1.2はPHPのinclude_path
設定を簡単に行えるようにするために静的メソッドであるsfToolkit::addIncludePath()
メソッドを追加します。
このメソッドは2つのパラメーターを受けつけます。
それは単一のパスかパスの配列と、ポジションを意味する文字列("front", "back"のどちらか)です。
第2引数は標準では"front"です。
// an example from sfPropelPlugin sfToolkit::addIncludePath(array( sfConfig::get('sf_root_dir'), sfConfig::get('sf_symfony_lib_dir'), realpath(dirname(__FILE__).'/../lib/vendor'), ));
アドミンジェネレーター
symfony1.2のためにアドミンジェネレーターは書き直されました。
そして新しいアドミンジェネレーターはフォームフレームワークに基づいています。
ジェネレータでモジュールを生成するためには、propel:generate-admin
タスクを次のように利用します。
$ php symfony propel:generate-admin backend Article
標準では、モジュールのためにRESTルーティングを追加します。 あなた自身でルーティングを作り、それをモデルクラス名の代わりに引数として渡すこともできます。
$ php symfony propel:generate-admin backend article
設定はgenerator.yml
で行います。
全ての設定はconfig
キーの下に存在します。
generator: class: sfPropelGenerator param: model_class: DemoCategory theme: admin non_verbose_templates: true with_show: false singular: ~ plural: ~ route_prefix: categories with_propel_route: 1 config: actions: ~ fields: ~ list: ~ filter: ~ form: ~ edit: ~ new: ~
edit
とnew
の新しいフォームのための異なる設定を持つことができるようになり、これらはform
設定から継承されています。
name
エントリーはlabel
に名前が変更されました。
古いアドミンジェネレータは後方互換性が保たれています。そのため、propel:init-admin
タスクを実行することで利用し続けることができます。
This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.