From 4b8a15265eda3b0aab91ab8af1db30750b803086 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sun, 30 Jul 2017 02:15:31 +0900 Subject: [PATCH 01/17] [ja] translate 3-5-migration-guide.rst --- ja/appendices/3-5-migration-guide.rst | 304 +++++++++++++++++++++++++- 1 file changed, 294 insertions(+), 10 deletions(-) diff --git a/ja/appendices/3-5-migration-guide.rst b/ja/appendices/3-5-migration-guide.rst index 30b84afeb1..999289037b 100644 --- a/ja/appendices/3-5-migration-guide.rst +++ b/ja/appendices/3-5-migration-guide.rst @@ -1,13 +1,297 @@ -3.5 Migration Guide -################### +3.5 移行ガイド +############## -.. note:: - The documentation is not currently supported in Japanese language for this - page. +CakePHP 3.5 は、3.4 の API の完全上位互換です。 +このページでは、3.5 の変更と改善についてのアウトラインを紹介します。 - Please feel free to send us a pull request on - `Github `_ or use the **Improve This Doc** - button to directly propose your changes. +3.5.xにアップグレードするには、次のComposerコマンドを実行してください。 - You can refer to the English version in the select top menu to have - information about this page's topic. +.. code-block:: bash + + php composer.phar require --update-with-dependencies "cakephp/cakephp:3.5.*" + +非推奨 +====== + +以下は、非推奨のメソッド、プロパティーと動作の一覧です。 +これらの機能は、4.0.0 以後に削除されるまで機能し続けます。 + +* ``Cake\Http\Client\CookieCollection`` は非推奨です。 + 代わりに ``Cake\Http\Cookie\CookieCollection`` を使用してください。 +* ``Cake\View\Helper\RssHelper`` は非推奨です。 + まれ利用されることがあるためRssHelperは非推奨となっています。 +* ``Cake\Controller\Component\CsrfComponent`` は非推奨です。 + 代わりに :ref:`csrf-middleware` を使用してください。 +* ``Cake\Datasource\TableSchemaInterface`` は非推奨です。 + ``Cake\Database\TableSchemaAwareInterface`` を使用してください。 +* ``Cake\Console\ShellDispatcher`` は非推奨です。アプリケーションでは + ``Cake\Console\CommandRunner`` を代わりに使用するように更新してください。 + +非推奨の複合 get / set メソッド +------------------------------- + +過去には、CakePHP は get / set モードの両方を提供する 'モーダル' メソッドを +利用していました。これらのメソッドにより、IDE の自動補完や、 +将来的に厳格な戻り値の型を追加する機能が複雑になります。 +これらの理由から、複合 get / set メソッドは、個別の get および +set メソッドに分割されています。 + +推奨されなくなり、 ``getX()`` と ``setX()`` メソッドに置き換えられた +メソッドのリストを次に示します。 + +``Cake\Cache\Cache`` + * ``config()`` + * ``registry()`` +``Cake\Console\Shell`` + * ``io()`` +``Cake\Console\ConsoleIo`` + * ``outputAs()`` +``Cake\Console\ConsoleOutput`` + * ``outputAs()`` +``Cake\Database\Connection`` + * ``logger()`` +``Cake\Datasource\TypedResultTrait`` + * ``returnType()`` +``Cake\Database\Log\LoggingStatement`` + * ``logger()`` +``Cake\Datasource\ModelAwareTrait`` + * ``modelType()`` +``Cake\Database\Query`` + * ``valueBinder()`` (今は ``getValueBinder()``) +``Cake\Datasource\QueryTrait`` + * ``eagerLoaded()`` (今は ``isEagerLoaded()``) +``Cake\Event\EventDispatcherTrait`` + * ``eventManager()`` +``Cake\Error\Debugger`` + * ``outputAs()`` (今は ``getOutputFormat()`` / ``setOutputFormat()``) +``Cake\Http\ServerRequest`` + * ``env()`` (今は ``getEnv()`` / ``withEnv()``) + * ``charset()`` (今は ``getCharset()`` / ``withCharset()``) +``Cake\I18n\I18n`` + * ``locale()`` + * ``translator()`` +``Cake\ORM\LocatorAwareTrait`` + * ``tableLocator()`` +``Cake\ORM\EntityTrait`` + * ``invalid()`` (今は ``getInvalid()``, ``setInvalid()``, + ``setInvalidField()``, そして ``getInvalidField()``) +``Cake\ORM\Table`` + * ``validator()`` +``Cake\Routing\RouteBuilder`` + * ``extensions()`` + * ``routeClass()`` +``Cake\Routing\RouteCollection`` + * ``extensions()`` +``Cake\TestSuite\TestFixture`` + * ``schema()`` +``Cake\Utility\Security`` + * ``salt()`` +``Cake\View\View`` + * ``template()`` + * ``layout()`` + * ``theme()`` + * ``templatePath()`` + * ``layoutPath()`` + * ``autoLayout()`` (今は ``isAutoLayoutEnabled()`` / ``enableAutoLayout()``) + +振る舞いの変更 +============== + +以下の変更は、API 互換性はありますが、あなたのアプリケーションに影響を及ぼし得る +振る舞いのわずかな差異があります。 + +* ``BehaviorRegistry`` 、 ``HelperRegistry`` 及び ``ComponentRegistry`` では、 + 未知のオブジェクト名で ``unload()`` が呼び出されたときに + 例外を発生させるようになりました。 この変更はタイポをより目立たせることで + エラーを見つけやすくしています。 +* ``HasMany`` は ``BelongsToMany`` と同様にアソシエーションのプロパティに + 空の値が設定されても正常に処理します。つまり、空の配列と同じ方法で + ``false`` 、 ``null`` 及び空の文字列を処理します。 + ``HasMany`` の場合、関連先の保存方法として ``replace`` が使用されているとき、 + 関連するすべてのレコードが削除/リンク解除されます。 + その結果、フォームを使用して空の文字列を渡すことによって、 + 関連するレコードをすべて削除/リンク解除することができます。 + これまではカスタムマーシャリングを作成する必要がありました。 +* ``ORM\Table::newEntity()`` は 変換された関連付けレコードが + ``dirty`` の場合にのみアソシエーションプロパティに ``dirty`` を + つけるようになりました。プロパティを含まない関連エンティティが作成される場合、 + 空のレコードには永続化させるためのフラグはつきません。 +* ``Http\Client`` はリクエストオブジェクトを作成するときに、 + ``cookie()`` の結果を使用しなくなりました。代わりに ``Cookie`` ヘッダーと + ``CookieCollection`` が使用できます。 + これは、クライアントにカスタムHTTPアダプターを使用しているときにのみ影響があります。 +* シェルを呼び出すときにサブコマンドに複数文字を用いる場合、 + 名前にはキャメルケースを使用する必要がありました。これからは + アンダースコアでサブコマンドを呼び出すことができます。例えば、 + ``cake tool initMyDb`` は ``cake tool init_my_db`` と呼び出すことができます。 + あなたのシェルが変換規則の異なる2つのサブコマンドを用いていた場合は + 最後に関連付けた規則のコマンドだけが機能します。 +* ``SecurityComponent`` はリクエストデータを持たないPOSTリクエストを捕獲します。 + この変更はデータベースのデフォルト値のみを使用してレコードを作成するアクションを + 保護するのに役立ちます。 +* ``Cake\ORM\Table::addBehavior()`` と ``removeBehavior()`` は ``$this`` を + 返すようになりました。これは、テーブルオブジェクトを + 流れるようなインターフェイスで定義するのに便利です。 +* キャッシュエンジンは失敗または誤って構成されたときに例外を発生させなくなりました。 + 代わりに、操作不能な ``NullEngine`` としてフォールバックさせます。フォールバックは + エンジンごとに定義することができます。 + 詳しくは、 :ref:`configured ` をご覧ください +* ``Cake\Database\Type\DateTimeType`` は以前からのフォーマットに加えて + ISO-8859-1 でフォーマットされた日付文字列(例えば、 2017-07-09T12:33:00+00:02) を + 変換するようになりました。DateTimeTypeのサブクラスを作成している場合は + コードを更新する必要があります。 + +新機能の追加 +============ + +スコープ付きミドルウェア +------------------------ + +特定のURLスコープのルートに条件付きでミドルウェアを適用できるようになりました。 +これにより、ミドルウェア内部でURLチェックコードを記述せずに、 +アプリケーションのさまざまな部分に対応するミドルウェア層を構築できます。 +詳しくは、 :ref:`connecting-scoped-middleware` をご覧ください。 + +新しいコンソールランナー +------------------------ + +3.5.0 では ``Cake\Console\CommandRunner`` が追加されました。このクラスは +``Cake\Console\CommandCollection`` とともに、CLI環境と新しい +``Application`` クラスを統合します。 ``Application`` クラスは +``console()`` フックを実装できるようになりました。これは、どのCLIコマンドが +公開されているか、それらがどのように命名されているか、シェルが +どのように依存関係を取得するかを完全に制御できます。この新しいクラスを採用するには +``bin/cake.php`` のファイルの内容を +`こちら `_ の +ファイルに置き換える必要があります。 + + +キャッシュエンジンフォールバック +-------------------------------- + +キャッシュエンジンは、 ``fallback`` キーを用いて定義できるようになりました。 +このキーは処理エンジンが誤って設定されている場合(または使用できない場合)に +フォールバックを使用する構成を定義するものです。 +詳しくは :ref:`cache-configuration-fallback` のフォールバックの設定をご覧ください。 + +コンソールの結合テスト +---------------------- + +``Cake\TestSuite\ConsoleIntegrationTestCase`` クラスが追加され、 +コンソールアプリケーションの結合テストがより簡単になりました。 +詳しくは、 :ref:`console-integration-testing` をご覧ください。 +このテストクラスは、現在の ``Cake\Console\ShellDispatcher`` および +新たに追加された ``Cake\Console\CommandRunner`` と完全に互換性があります。 + +コア +---- + +* ``Cake\Core\Configure::read()`` は、要求されたキーが存在しない場合に用いる + デフォルト値をサポートするようになりました。 +* ``Cake\Core\ObjectRegistry`` に、 ``Countable`` および + ``IteratorAggregate`` インターフェースが実装されました。 + +コンソール +---------- + +* ``Cake\Console\ConsoleOptionParser::setHelpAlias()`` が追加されました。 + このメソッドを使用するすることで、ヘルプ出力を生成するときに使用される + コマンド名を設定できます。デフォルトは ``cake`` です。 +* ``Cake\Console\ShellDispatcher`` の代わりに ``Cake\Console\CommandRunnner`` が + 追加されました。 +* アプリケーションが提供するコマンドラインツールを定義するための + インターフェイスとして ``Cake\Console\CommandCollection`` が追加されました。 + +データベース +------------ + +* SQLiteドライバに ``mask`` オプションが追加されました。このオプションは + SQLiteデータベースファイルが作成されたときのアクセス権限の設定を可能にします。 + +データソース +------------ + +* ``Cake\Datasource\SchemaInterface`` オプションが追加されました。 +* ``smallinteger`` と ``tinyinteger`` に新しい抽象型が追加されました。 + 既存の ``SMALLINT`` 型と ``TINYINT`` 型がこれらの新しい抽象型として + 反映されるようになりました。 ``TINYINT(1)`` 型は、引き続きMySQLで + boolean型として扱われます。 +* ``Cake\Datasource\PaginatorInterface`` が追加されました。 + ``PaginatorComponent`` は、このインターフェイスを通してページネーションを + 取り扱うようになりました。これにより、他のORMと似た実装で + コンポーネントによってページネーションをできるようになりました。 +* ``Cake\Datasource\Paginator`` を追加して ``ORM/Database/QueryInstances`` を + ページネーションできるようにしました。 + +イベント +-------- + +* ``Cake\Event\EventManager::on()`` と ``off()`` はチェーン実装可能になり、 + 複数のイベントを一度に設定することが容易になりました。 + +Http +---- + +* 新たに ``Cookie`` と ``CookieCollection`` クラスが追加されました。 + これらのクラスを使用するとオブジェクト指向でクッキーを扱うことができます。 + また、これらは ``Cake\Http\ServerRequest`` 、 ``Cake\Http\Response`` 、 + ``Cake\Http\Client\Response`` で利用できます。 + 詳しくは、 :ref:`request-cookies` と :ref:`response-cookies` をご覧ください。 +* セキュリティヘッダーの適用が容易になる新しいミドルウエアが追加されました。 + 詳しくは、 :ref:`security-header-middleware` をご覧ください。 +* クッキーデータを透過的に暗号化する新しいミドルウェアが追加されました。 + 詳しくは、 :ref:`encrypted-cookie-middleware` をご覧ください。 +* CSRFに対する保護を容易にする、新しいミドルウェアが追加されました。 + 詳しくは、 :ref:`csrf-middleware` をご覧ください。 +* ``Cake\Http\Client::addCookie()`` が追加されました。 + これはクライアントインスタンスへのクッキー追加を容易にします。 + +ORM +--- + +* ``Cake\ORM\Query::contain()`` は一つのアソシエーションが入る場合、 + ラッピング配列なしで呼び出すことができるようになり。つまり、 + ``contain('Comments', function (){ ... });`` で動作するようになります。 + この変更で ``leftJoinWith()`` や ``matching()`` のような、他のeagerloading関連の + メソッドと ``contain()`` の一貫性を与えています。 + +ルーティング +------------ + +* ``Cake\Routing\Router::reverseToArray()`` が追加されました。 + このメソッドを使用することで、リクエストオブジェクトをURL文字列の生成に + 使用できる配列に変換できます。 +* ``Cake\Routing\RouteBuilder::resources()`` に ``path`` オプションが追加されました。 + このオプションを使用するとコントローラ名に一致しないリソースパスを + 作ることができます。 +* ``Cake\Routing\RouteBuilder`` に、特定のHTTPメソッドのルートを作成するメソッドが + 追加されました。例えば ``get()`` や ``post()`` が追加されています。 +* ``Cake\Routing\RouteBuilder::loadPlugin()`` が追加されました。 +* ``Cake\Routing\Route`` のオプション定義メソッドは + 流れるようなインターフェイスになりました。 + +TestSuite +--------- + +* ``IntegrationTestCase::head()`` が追加されました。 +* ``IntegrationTestCase::options()`` が追加されました。 +* ``IntegrationTestCase::disableErrorHandlerMiddleware()`` が追加されました。 + 結合テストのデバッグがより簡単になりました。 + +バリデーション +-------------- +* ``Cake\Validation\Validator::regex()`` が追加されました。 + これは正規表現パターンでデータ検証を今までより便利に行う方法です。 +* ``Cake\Validation\Validator::addDefaultProvider()`` が追加されました。 + このメソッドでアプリケーションで作成されたすべてのバリデーターに + バリデーションプロバイダを挿入できます。 +* ``Cake\Validation\ValidatorAwareInterface`` が追加されました。 + これは、 ``Cake\Validation\ValidatorAwareTrait`` によって実装されるメソッドを + 定義します。 + +View +---- + +* ``Cake\View\Helper\PaginatorHelper::limitControl()`` が追加されました。 + このメソッドを使用すると、ページネートされた結果セットのlimit値を + 更新するセレクトボックスのフォームを作ることができます。 From 4a0929a4af769fb21dee75b95cd08bcf10c37ba2 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Tue, 1 Aug 2017 13:09:26 +0900 Subject: [PATCH 02/17] fix: Be in accordance with Japanese-Translation-Rules --- ja/appendices/3-5-migration-guide.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ja/appendices/3-5-migration-guide.rst b/ja/appendices/3-5-migration-guide.rst index 999289037b..fe8f0bcb04 100644 --- a/ja/appendices/3-5-migration-guide.rst +++ b/ja/appendices/3-5-migration-guide.rst @@ -104,7 +104,7 @@ set メソッドに分割されています。 未知のオブジェクト名で ``unload()`` が呼び出されたときに 例外を発生させるようになりました。 この変更はタイポをより目立たせることで エラーを見つけやすくしています。 -* ``HasMany`` は ``BelongsToMany`` と同様にアソシエーションのプロパティに +* ``HasMany`` は ``BelongsToMany`` と同様にアソシエーションのプロパティーに 空の値が設定されても正常に処理します。つまり、空の配列と同じ方法で ``false`` 、 ``null`` 及び空の文字列を処理します。 ``HasMany`` の場合、関連先の保存方法として ``replace`` が使用されているとき、 @@ -113,8 +113,8 @@ set メソッドに分割されています。 関連するレコードをすべて削除/リンク解除することができます。 これまではカスタムマーシャリングを作成する必要がありました。 * ``ORM\Table::newEntity()`` は 変換された関連付けレコードが - ``dirty`` の場合にのみアソシエーションプロパティに ``dirty`` を - つけるようになりました。プロパティを含まない関連エンティティが作成される場合、 + ``dirty`` の場合にのみアソシエーションプロパティーに ``dirty`` を + つけるようになりました。プロパティーを含まない関連エンティティーが作成される場合、 空のレコードには永続化させるためのフラグはつきません。 * ``Http\Client`` はリクエストオブジェクトを作成するときに、 ``cookie()`` の結果を使用しなくなりました。代わりに ``Cookie`` ヘッダーと @@ -205,7 +205,7 @@ set メソッドに分割されています。 データベース ------------ -* SQLiteドライバに ``mask`` オプションが追加されました。このオプションは +* SQLiteドライバーに ``mask`` オプションが追加されました。このオプションは SQLiteデータベースファイルが作成されたときのアクセス権限の設定を可能にします。 データソース @@ -262,7 +262,7 @@ ORM このメソッドを使用することで、リクエストオブジェクトをURL文字列の生成に 使用できる配列に変換できます。 * ``Cake\Routing\RouteBuilder::resources()`` に ``path`` オプションが追加されました。 - このオプションを使用するとコントローラ名に一致しないリソースパスを + このオプションを使用するとコントローラー名に一致しないリソースパスを 作ることができます。 * ``Cake\Routing\RouteBuilder`` に、特定のHTTPメソッドのルートを作成するメソッドが 追加されました。例えば ``get()`` や ``post()`` が追加されています。 @@ -284,7 +284,7 @@ TestSuite これは正規表現パターンでデータ検証を今までより便利に行う方法です。 * ``Cake\Validation\Validator::addDefaultProvider()`` が追加されました。 このメソッドでアプリケーションで作成されたすべてのバリデーターに - バリデーションプロバイダを挿入できます。 + バリデーションプロバイダーを挿入できます。 * ``Cake\Validation\ValidatorAwareInterface`` が追加されました。 これは、 ``Cake\Validation\ValidatorAwareTrait`` によって実装されるメソッドを 定義します。 From 554ca9bc26c131a69cf20820b1999f6245885f1b Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Thu, 3 Aug 2017 19:52:03 +0900 Subject: [PATCH 03/17] [ja] #5051 copy from en to ja --- ja/core-libraries/caching.rst | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ja/core-libraries/caching.rst b/ja/core-libraries/caching.rst index cc6e251225..08032ffbc4 100644 --- a/ja/core-libraries/caching.rst +++ b/ja/core-libraries/caching.rst @@ -120,6 +120,38 @@ DSN を使用するとき、追加のクエリー文字列要素としてパラ FileEndine 使用時に、正しいパーミッションでのキャッシュファイルを指定して作成するには、 ``mask`` オプションの設定が必要です。 +.. _cache-configuration-fallback: + +Configuring Cache Fallbacks +--------------------------- + +In the event that an engine is not available, such as the ``FileEngine`` trying +to write to an unwritable folder or the ``RedisEngine`` failing to connect to +Redis, the engine will fall back to the noop ``NullEngine`` and trigger a loggable +error. This prevents the application from throwing an uncaught exception due to +cache failure. + +You can configure Cache configurations to fall back to a specified config using +the ``fallback`` configuration key:: + + Cache::config('redis', [ + 'className' => 'Redis', + 'duration' => '+1 hours', + 'prefix' => 'cake_redis_', + 'host' => '127.0.0.1', + 'port' => 6379, + 'fallback' => 'default', + ]); + +If the Redis server unexpectedly failed, writing to the ``redis`` cache +configuration would fall back to writing to the ``default`` cache configuration. +If writing to the ``default`` cache configuration *also* failed in this scenario, the +engine would fall back once again to the ``NullEngine`` and prevent the application +from throwing an uncaught exception. + +.. versionadded:: 3.5.0 + Cache engine fallbacks were added. + 設定されたキャッシュエンジンを削除する -------------------------------------- From b45889776c9a90eab382f28f06d189da809d7466 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Thu, 3 Aug 2017 20:11:38 +0900 Subject: [PATCH 04/17] [ja] #4912 copy from en to ja --- ja/controllers/middleware.rst | 69 ++++ ja/controllers/request-response.rst | 590 ++++++++++++++++++++++++++++ 2 files changed, 659 insertions(+) diff --git a/ja/controllers/middleware.rst b/ja/controllers/middleware.rst index 0733480986..5fd61d6043 100644 --- a/ja/controllers/middleware.rst +++ b/ja/controllers/middleware.rst @@ -19,6 +19,11 @@ CakePHP はいくつかのミドルウェアを既成で提供します。 リクエストにルーティングパラメーターを割り当てるために ``Router`` を使用します。 * ``Cake\I18n\Middleware\LocaleSelectorMiddleware`` はブラウザーによって送られる ``Accept-Language`` ヘッダーによって自動で言語を切り替えられるようにします。 +* ``Cake\Http\Middleware\EncryptedCookieMiddleware`` gives you the ability to + manipulate encrypted cookies in case you need to manipulate cookie with + obfuscated data. +* ``Cake\Http\Middleware\CsrfProtectionMiddleware`` adds CSRF protection to your + application. .. _using-middleware: @@ -249,6 +254,70 @@ PSR-7 リクエストとレスポンス } } +.. _security-header-middleware: + +Adding Security Headers +======================= + +The ``SecurityHeaderMiddleware`` layer makes it easy to apply security related +headers to your application. Once setup the middleware can apply the following +headers to responses: + +* ``X-Content-Type-Options`` +* ``X-Download-Options`` +* ``X-Frame-Options`` +* ``X-Permitted-Cross-Domain-Policies`` +* ``Referrer-Policy`` + +This middleware is configured using a fluent interface before it is applied to +your application's middleware stack:: + + use Cake\Http\Middleware\SecurityHeadersMiddleware; + + $headers = new SecurityHeadersMiddleware(); + $headers + ->setCrossDomainPolicy() + ->setReferrerPolicy() + ->setXFrameOptions() + ->setXssProtection() + ->noOpen() + ->noSniff(); + + $middlewareQueue->add($headers); + +.. versionadded:: 3.5.0 + The ``SecurityHeadersMiddleware`` was added in 3.5.0 + +.. _encrypted-cookie-middleware: + +Encrypted Cookie Middleware +=========================== + +If your application has cookies that contain data you want to obfuscate and +protect against user tampering, you may can use CakePHP's encrypted cookie +middleware to transparently encrypt and decrypt cookie data via middleware. +Cookie data is encrypted with via OpenSSL using AES:: + + use Cake\Http\Middleware\EncryptedCookieMiddleware; + + $cookies = new EncryptedCookieMiddleware( + // Names of cookies to protect + ['secrets', 'protected'], + Configure::read('Security.cookieKey') + ); + + $middlewareQueue->add($cookies); + +.. note:: + It is recommended that the encryption key you use for cookie data, is used + *exclusively* for cookie data. + +The encryption algorithms and padding style used by the cookie middleware are +backwards compatible with ``CookieComponent`` from earlier versions of CakePHP. + +.. versionadded:: 3.5.0 + The ``EncryptedCookieMiddleware`` was added in 3.5.0 + .. _adding-http-stack: 既存アプリケーションへの新しい HTTP スタック追加 diff --git a/ja/controllers/request-response.rst b/ja/controllers/request-response.rst index 0b57e63ea1..34d97aa132 100644 --- a/ja/controllers/request-response.rst +++ b/ja/controllers/request-response.rst @@ -409,6 +409,497 @@ Accept ヘッダーの確認 $acceptsSpanish = $this->request->acceptLanguage('es-es'); +.. _request-cookies: + +Cookies +------- + +Request cookies can be read through a number of methods:: + + // Get the cookie value, or null if the cookie is missing. + $rememberMe = $this->request->getCookie('remember_me'); + + // Read the value, or get the default of 0 + $rememberMe = $this->request->getCookie('remember_me', 0); + + // Get all cookies as an hash + $cookies = $this->request->getCookieParams(); + + // Get a CookieCollection instance (starting with 3.5.0) + $cookies = $this->request->getCookieCollection() + +See the :php:class:`Cake\\Http\\Cookie\\CookieCollection` documentation for how +to work with cookie collection. + +.. versionadded:: 3.5.0 + ``ServerRequest::getCookieCollection()`` was added in 3.5.0 + +.. index:: $this->response + +Response +======== + +.. php:class:: Response + +:php:class:`Cake\\Http\\Response` is the default response class in CakePHP. +It encapsulates a number of features and functionality for generating HTTP +responses in your application. It also assists in testing, as it can be +mocked/stubbed allowing you to inspect headers that will be sent. +Like :php:class:`Cake\\Http\\ServerRequest`, :php:class:`Cake\\Http\\Response` +consolidates a number of methods previously found on :php:class:`Controller`, +:php:class:`RequestHandlerComponent` and :php:class:`Dispatcher`. The old +methods are deprecated in favour of using :php:class:`Cake\\Http\\Response`. + +``Response`` provides an interface to wrap the common response-related +tasks such as: + +* Sending headers for redirects. +* Sending content type headers. +* Sending any header. +* Sending the response body. + +Dealing with Content Types +-------------------------- + +.. php:method:: withType($contentType = null) + +You can control the Content-Type of your application's responses with +:php:meth:`Cake\\Http\\Response::withType()`. If your application needs to deal +with content types that are not built into Response, you can map them with +``type()`` as well:: + + // Add a vCard type + $this->response->type(['vcf' => 'text/v-card']); + + // Set the response Content-Type to vcard. + $this->response = $this->response->withType('vcf'); + + // Prior to 3.4.0 + $this->response->type('vcf'); + +Usually, you'll want to map additional content types in your controller's +:php:meth:`~Controller::beforeFilter()` callback, so you can leverage the +automatic view switching features of :php:class:`RequestHandlerComponent` if you +are using it. + +.. _cake-response-file: + +Sending Files +------------- + +.. php:method:: withFile($path, $options = []) + +There are times when you want to send files as responses for your requests. +You can accomplish that by using :php:meth:`Cake\\Http\\Response::withFile()`:: + + public function sendFile($id) + { + $file = $this->Attachments->getFile($id); + $response = $this->response->withFile($file['path']); + // Return the response to prevent controller from trying to render + // a view. + return $response; + } + + // Prior to 3.4.0 + $file = $this->Attachments->getFile($id); + $this->response->file($file['path']); + // Return the response to prevent controller from trying to render + // a view. + return $this->response; + +As shown in the above example, you must pass the file path to the method. +CakePHP will send a proper content type header if it's a known file type listed +in `Cake\\Http\\Reponse::$_mimeTypes`. You can add new types prior to calling +:php:meth:`Cake\\Http\\Response::withFile()` by using the +:php:meth:`Cake\\Http\\Response::withType()` method. + +If you want, you can also force a file to be downloaded instead of displayed in +the browser by specifying the options:: + + $response = $this->response->withFile( + $file['path'], + ['download' => true, 'name' => 'foo'] + ); + + // Prior to 3.4.0 + $this->response->file( + $file['path'], + ['download' => true, 'name' => 'foo'] + ); + +The supported options are: + +name + The name allows you to specify an alternate file name to be sent to + the user. +download + A boolean value indicating whether headers should be set to force + download. + +Sending a String as File +------------------------ + +You can respond with a file that does not exist on the disk, such as a pdf or an +ics generated on the fly from a string:: + + public function sendIcs() + { + $icsString = $this->Calendars->generateIcs(); + $response = $this->response; + $response->body($icsString); + + $response = $response->withType('ics'); + + // Optionally force file download + $response = $response->withDownload('filename_for_download.ics'); + + // Return response object to prevent controller from trying to render + // a view. + return $response; + } + +Callbacks can also return the body as a string:: + + $path = '/some/file.png'; + $this->response->body(function () use ($path) { + return file_get_contents($path); + }); + +Setting Headers +--------------- + +.. php:method:: withHeader($header, $value) + +Setting headers is done with the :php:meth:`Cake\\Http\\Response::withHeader()` +method. Like all of the PSR-7 interface methods, this method returns a *new* +instance with the new header:: + + // Add/replace a header + $response = $response->withHeader('X-Extra', 'My header'); + + // Set multiple headers + $response = $response->withHeader('X-Extra', 'My header') + ->withHeader('Location', 'http://example.com'); + + // Append a value to an existing header + $response = $response->withAddedHeader('Set-Cookie', 'remember_me=1'); + + // Prior to 3.4.0 - Set a header + $this->response->header('Location', 'http://example.com'); + +Headers are not sent when set. Instead, they are held until the response is +emitted by ``Cake\Http\Server``. + +You can now use the convenience method +:php:meth:`Cake\\Http\\Response::withLocation()` to directly set or get the +redirect location header. + +Setting the Body +---------------- + +.. php:method:: withStringBody($string) + +To set a string as the response body, do the following:: + + // Set a string into the body + $response = $response->withStringBody('My Body'); + + // If you want a json response + $response = $response->withType('application/json') + ->withStringBody(json_encode(['Foo' => 'bar'])); + +.. versionadded:: 3.4.3 + ``withStringBody()`` was added in 3.4.3 + +.. php:method:: withBody($body) + +To set the response body, use the ``withBody()`` method, which is provided by the +:php:class:`Zend\\Diactoros\\MessageTrait`:: + + $response = $response->withBody($stream); + + // Prior to 3.4.0 - Set the body + $this->response->body('My Body'); + +Be sure that ``$stream`` is a :php:class:`Psr\\Http\\Message\\StreamInterface` object. +See below on how to create a new stream. + +You can also stream responses from files using :php:class:`Zend\\Diactoros\\Stream` streams:: + + // To stream from a file + use Zend\Diactoros\Stream; + + $stream = new Stream('/path/to/file', 'rb'); + $response = $response->withBody($stream); + +You can also stream responses from a callback using the ``CallbackStream``. This +is useful when you have resources like images, CSV files or PDFs you need to +stream to the client:: + + // Streaming from a callback + use Cake\Http\CallbackStream; + + // Create an image. + $img = imagecreate(100, 100); + // ... + + $stream = new CallbackStream(function () use ($img) { + imagepng($img); + }); + $response = $response->withBody($stream); + + // Prior to 3.4.0 you can use the following to create streaming responses. + $file = fopen('/some/file.png', 'r'); + $this->response->body(function () use ($file) { + rewind($file); + fpassthru($file); + fclose($file); + }); + +Setting the Character Set +------------------------- + +.. php:method:: withCharset($charset) + +Sets the charset that will be used in the response:: + + $this->response = $this->response->withCharset('UTF-8'); + + // Prior to 3.4.0 + $this->response->charset('UTF-8'); + +Interacting with Browser Caching +-------------------------------- + +.. php:method:: withDisabledCache() + +You sometimes need to force browsers not to cache the results of a controller +action. :php:meth:`Cake\\Http\\Response::withDisabledCache()` is intended for just +that:: + + public function index() + { + // Disable caching + $this->response = $this->response->withDisabledCache(); + } + +.. warning:: + + Disabling caching from SSL domains while trying to send + files to Internet Explorer can result in errors. + +.. php:method:: withCache($since, $time = '+1 day') + +You can also tell clients that you want them to cache responses. By using +:php:meth:`Cake\\Http\\Response::withCache()`:: + + public function index() + { + // Enable caching + $this->response = $this->response->withCache('-1 minute', '+5 days'); + } + +The above would tell clients to cache the resulting response for 5 days, +hopefully speeding up your visitors' experience. +The ``withCache()`` method sets the ``Last-Modified`` value to the first +argument. ``Expires`` header and the ``max-age`` directive are set based on the +second parameter. Cache-Control's ``public`` directive is set as well. + +.. _cake-response-caching: + +Fine Tuning HTTP Cache +---------------------- + +One of the best and easiest ways of speeding up your application is to use HTTP +cache. Under this caching model, you are only required to help clients decide if +they should use a cached copy of the response by setting a few headers such as +modified time and response entity tag. + +Rather than forcing you to code the logic for caching and for invalidating +(refreshing) it once the data has changed, HTTP uses two models, expiration and +validation, which usually are much simpler to use. + +Apart from using :php:meth:`Cake\\Http\\Response::withCache()`, you can also use +many other methods to fine-tune HTTP cache headers to take advantage of browser +or reverse proxy caching. + +The Cache Control Header +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. php:method:: withSharable($public, $time = null) + +Used under the expiration model, this header contains multiple indicators that +can change the way browsers or proxies use the cached content. A +``Cache-Control`` header can look like this:: + + Cache-Control: private, max-age=3600, must-revalidate + +``Response`` class helps you set this header with some utility methods that will +produce a final valid ``Cache-Control`` header. The first is the +``withSharable()`` method, which indicates whether a response is to be +considered sharable across different users or clients. This method actually +controls the ``public`` or ``private`` part of this header. Setting a response +as private indicates that all or part of it is intended for a single user. To +take advantage of shared caches, the control directive must be set as public. + +The second parameter of this method is used to specify a ``max-age`` for the +cache, which is the number of seconds after which the response is no longer +considered fresh:: + + public function view() + { + // ... + // Set the Cache-Control as public for 3600 seconds + $this->response = $this->response->withSharable(true, 3600); + } + + public function my_data() + { + // ... + // Set the Cache-Control as private for 3600 seconds + $this->response = $this->response->withSharable(false, 3600); + } + +``Response`` exposes separate methods for setting each of the directives in +the ``Cache-Control`` header. + +The Expiration Header +~~~~~~~~~~~~~~~~~~~~~ + +.. php:method:: withExpires($time) + +You can set the ``Expires`` header to a date and time after which the response +is no longer considered fresh. This header can be set using the +``withExpires()`` method:: + + public function view() + { + $this->response = $this->response->withExpires('+5 days'); + } + +This method also accepts a :php:class:`DateTime` instance or any string that can +be parsed by the :php:class:`DateTime` class. + +The Etag Header +~~~~~~~~~~~~~~~ + +.. php:method:: withEtag($tag, $weak = false) + +Cache validation in HTTP is often used when content is constantly changing, and +asks the application to only generate the response contents if the cache is no +longer fresh. Under this model, the client continues to store pages in the +cache, but it asks the application every time +whether the resource has changed, instead of using it directly. +This is commonly used with static resources such as images and other assets. + +The ``withEtag()`` method (called entity tag) is a string +that uniquely identifies the requested resource, as a checksum does for a file, +in order to determine whether it matches a cached resource. + +To take advantage of this header, you must either call the +``checkNotModified()`` method manually or include the +:doc:`/controllers/components/request-handling` in your controller:: + + public function index() + { + $articles = $this->Articles->find('all'); + $response = $this->response->withEtag($this->Articles->generateHash($articles)); + if ($response->checkNotModified($this->request)) { + return $response; + } + $this->response = $response; + // ... + } + +.. note:: + + Most proxy users should probably consider using the Last Modified Header + instead of Etags for performance and compatibility reasons. + +The Last Modified Header +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. php:method:: withModified($time) + +Also, under the HTTP cache validation model, you can set the ``Last-Modified`` +header to indicate the date and time at which the resource was modified for the +last time. Setting this header helps CakePHP tell caching clients whether the +response was modified or not based on their cache. + + +To take advantage of this header, you must either call the +``checkNotModified()`` method manually or include the +:doc:`/controllers/components/request-handling` in your controller:: + + public function view() + { + $article = $this->Articles->find()->first(); + $response = $this->response->withModified($article->modified); + if ($response->checkNotModified($this->request)) { + return $response; + } + $this->response; + // ... + } + +The Vary Header +~~~~~~~~~~~~~~~ + +.. php:method:: withVary($header) + +In some cases, you might want to serve different content using the same URL. +This is often the case if you have a multilingual page or respond with different +HTML depending on the browser. Under such circumstances you can use the ``Vary`` +header:: + + $response = $this->response->withVary('User-Agent'); + $response = $this->response->withVary('Accept-Encoding', 'User-Agent'); + $response = $this->response->withVary('Accept-Language'); + +Sending Not-Modified Responses +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. php:method:: checkNotModified(Request $request) + +Compares the cache headers for the request object with the cache header from the +response and determines whether it can still be considered fresh. If so, deletes +the response content, and sends the `304 Not Modified` header:: + + // In a controller action. + if ($this->response->checkNotModified($this->request)) { + return $this->response; + } + +.. _response-cookies: + +Setting Cookies +=============== + +Cookies can be added to response using either an array or a :php:class:`Cookie`` +object:: + + // Add a cookie as an array using the immutable API (3.4.0+) + $this->response = $this->response->withCookie('remember_me', [ + 'value' => 'yes', + 'path' => '/', + 'httpOnly' => true, + 'secure' => false, + 'expire' => strtotime('+1 year') + ]); + + // Before 3.4.0 + $this->response->cookie('remember', [ + 'value' => 'yes', + 'path' => '/', + 'httpOnly' => true, + 'secure' => false, + 'expire' => strtotime('+1 year') + ]); + +See the :ref:`creating-cookies` section for how to use the cookie object. + + .. index:: $this->response レスポンス @@ -866,6 +1357,105 @@ CakePHP 3.4.0 以降、レスポンスオブジェクトはレスポンスを不 $this->response = $this->response->withHeader('X-CakePHP', 'yes!'); +.. php:namespace:: Cake\Http\Cookie + +Cookie Collections +================== + +.. php:class:: CookieCollection + +``CookieCollection`` objects are accessible from the request and response objects. +They let you interact with groups of cookies using immutable patterns, which +allow the immutability of the request and response to be preserved. + +.. _creating-cookies: + +Creating Cookies +---------------- + +``Cookie`` objects can be defined through constructor objects, or by using the +fluent interface that follows immutable patterns:: + + use Cake\Http\Cookie\Cookie; + + // All arguments in the constructor + $cookie = new Cookie( + 'remember_me', // name + 1, // value + new DateTime('+1 year'), // expiration time, if applicable + '/', // path, if applicable + 'example.com', // domain, if applicable + false, // secure only? + true // http only ? + ); + + // Using the builder methods + $cookie = (new Cookie('remember_me')) + ->withValue('1') + ->withExpiry(new DateTime('+1 year')) + ->withPath('/') + ->withDomain('example.com') + ->withSecure(false) + ->withHttpOnly(true); + +Once you have created a cookie, you can add it to a new or existing +``CookieCollection``:: + + use Cake\Http\Cookie\CookieCollection; + + // Create a new collection + $cookies = new CookieCollection([$cookie]); + + // Add to an existing collection + $cookies = $cookies->add($cookie); + + // Remove a cookie by name + $cookies = $cookies->remove('remember_me'); + +.. note:: + Remember that collections are immutable and adding cookies into, or removing + cookies from a collection, creates a *new* collection object. + +You should use the ``withCookie()`` method to add cookies to ``Response`` +objects as it is simpler to use:: + + $response = $this->response->withCookie($cookie); + +Cookies set to responses can be encrypted using the +:ref:`encrypted-cookie-middleware`. + +Reading Cookies +--------------- + +Once you have a ``CookieCollection`` instance, you can access the cookies it +contains:: + + // Check if a cookie exists + $cookies->has('remember_me'); + + // Get the number of cookies in the collection + count($cookies); + + // Get a cookie instance + $cookie = $cookies->get('remember_me'); + +Once you have a ``Cookie`` object you can interact with it's state and modify +it. Keep in mind that cookies are immutable, so you'll need to update the +collection if you modify a cookie:: + + // Get the value + $value = $cookie->getValue() + + // Access data inside a JSON value + $id = $cookie->read('User.id'); + + // Check state + $cookie->isHttpOnly(); + $cookie->isSecure(); + +.. versionadded:: 3.5.0 + ``CookieCollection`` and ``Cookie`` were added in 3.5.0. + .. meta:: :title lang=ja: リクエストとレスポンスオブジェクト :keywords lang=ja: request controller,request parameters,array indexes,purpose index,response objects,domain information,request object,request data,interrogating,params,previous versions,introspection,dispatcher,rout,data structures,arrays,ip address,migration,indexes,cakephp,PSR-7,immutable From e79ad45c390c4cd3317739480768eb2bfe03f0d1 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Thu, 3 Aug 2017 20:21:28 +0900 Subject: [PATCH 05/17] [ja] #4976 copy from en to ja --- ja/controllers/components/cookie.rst | 4 ++ ja/controllers/components/csrf.rst | 4 ++ ja/controllers/middleware.rst | 57 ++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/ja/controllers/components/cookie.rst b/ja/controllers/components/cookie.rst index a684a52de5..8e51d22b8b 100644 --- a/ja/controllers/components/cookie.rst +++ b/ja/controllers/components/cookie.rst @@ -8,6 +8,10 @@ CookieComponent は PHP に組み込まれている ``setcookie()`` メソッドのラッパーです。 このコンポーネントは、 Cookie の扱いを容易にし、 Cookie のデータを暗号化します。 +.. deprecated:: 3.5.0 + You should use :ref:`encrypted-cookie-middleware` instead of + ``CookieComponent``. + Cookie の設定 ================= diff --git a/ja/controllers/components/csrf.rst b/ja/controllers/components/csrf.rst index 57850c5820..c5489a02cb 100644 --- a/ja/controllers/components/csrf.rst +++ b/ja/controllers/components/csrf.rst @@ -26,6 +26,10 @@ hidden フィールドに CSRF トークンが追加されます。 ``Controller 例外の型が :php:class:`Cake\\Network\\Exception\\ForbiddenException` から :php:class:`Cake\\Network\\Exception\\InvalidCsrfTokenException` に変更されました。 +.. deprecated:: 3.5.0 + You should use :ref:`csrf-middleware` instead of + ``CsrfComponent``. + CsrfComponent を使用する ============================ diff --git a/ja/controllers/middleware.rst b/ja/controllers/middleware.rst index 5fd61d6043..833a74a5a8 100644 --- a/ja/controllers/middleware.rst +++ b/ja/controllers/middleware.rst @@ -318,6 +318,63 @@ backwards compatible with ``CookieComponent`` from earlier versions of CakePHP. .. versionadded:: 3.5.0 The ``EncryptedCookieMiddleware`` was added in 3.5.0 +.. _csrf-middleware: + +Cross Site Request Forgery (CSRF) Middleware +============================================ + +CSRF protection can be applied to your entire application, or to specific scopes +by applying the ``CsrfProtectionMiddleware`` to your middleware stack:: + + use Cake\Http\Middleware\CsrfProtectionMiddleware; + + $options = [ + // ... + ]; + $csrf = new CsrfProtectionMiddleware($options); + + $middlewareQueue->add($csrf); + +Options can be passed into the middleware's constructor. +The available configuration options are: + +- ``cookieName`` The name of the cookie to send. Defaults to ``csrfToken``. +- ``expiry`` How long the CSRF token should last. Defaults to browser session. +- ``secure`` Whether or not the cookie will be set with the Secure flag. That is, + the cookie will only be set on a HTTPS connection and any attempt over normal HTTP + will fail. Defaults to ``false``. +- ``field`` The form field to check. Defaults to ``_csrfToken``. Changing this + will also require configuring FormHelper. + +When enabled, you can access the current CSRF token on the request object:: + + $token = $this->request->getParam('_csrfToken'); + +.. versionadded:: 3.5.0 + The ``CsrfProtectionMiddleware`` was added in 3.5.0 + + +Integration with FormHelper +--------------------------- + +The ``CsrfProtectionMiddleware`` integrates seamlessly with ``FormHelper``. Each +time you create a form with ``FormHelper``, it will insert a hidden field containing +the CSRF token. + +.. note:: + + When using CSRF protection you should always start your forms with the + ``FormHelper``. If you do not, you will need to manually create hidden inputs in + each of your forms. + +CSRF Protection and AJAX Requests +--------------------------------- + +In addition to request data parameters, CSRF tokens can be submitted through +a special ``X-CSRF-Token`` header. Using a header often makes it easier to +integrate a CSRF token with JavaScript heavy applications, or XML/JSON based API +endpoints. + .. _adding-http-stack: 既存アプリケーションへの新しい HTTP スタック追加 From 25714f7ae1ca337dc6e2384b400ec2e3bc69bc9e Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Thu, 3 Aug 2017 20:27:25 +0900 Subject: [PATCH 06/17] [ja] #4984 copy from en to ja --- ja/development/routing.rst | 90 +++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/ja/development/routing.rst b/ja/development/routing.rst index 4514c758a9..693edeea99 100644 --- a/ja/development/routing.rst +++ b/ja/development/routing.rst @@ -40,14 +40,14 @@ URL の構造を全部のコードの書き直しをせずにリファクタリ index メソッドを実行します。時々、複数のパラメーターを受け取る動的なルートが 必要になると思います。それが必要になるケースは、例えば、記事の内容を表示するためのルートです。 :: - Router::connect('/articles/*', ['controller' => 'Articles', 'action' => 'view']); + $routes->connect('/articles/*', ['controller' => 'Articles', 'action' => 'view']); 上記のルートは、 ``/articles/15`` のような URL を受け取り、 ``ArticlesController`` の ``view(15)`` メソッドを呼びます。しかし、これは ``/articles/foobar`` のような URL からの アクセスを防ぐわけではありません。もし、あなたが望むなら、いくつかのパラメーターを正規表現に従うように 修正できます。 :: - Router::connect( + $routes->connect( '/articles/:id', ['controller' => 'Articles', 'action' => 'view'], ['id' => '\d+', 'pass' => ['id']] @@ -71,14 +71,15 @@ URL 文字列を生成できることを意味します。 :: ルートは一意の名前を付けることもできます。これは、リンクを構築する際に、 ルーティングパラメーターをそれぞれ指定する代わりに、ルートを素早く参照することができます。 :: - use Cake\Routing\Router; - - Router::connect( + // In routes.php + $routes->connect( '/login', ['controller' => 'Users', 'action' => 'login'], ['_name' => 'login'] ); + use Cake\Routing\Router; + echo Router::url(['_name' => 'login']); // 出力結果 /login @@ -106,11 +107,10 @@ URL 文字列を生成できることを意味します。 :: ルートを接続 ============ -.. php:staticmethod:: connect($route, $defaults = [], $options = []) +.. php:method:: connect($route, $defaults = [], $options = []) コードを :term:`DRY` に保つために 'ルーティングスコープ' を使用してください。 ルーティングスコープはコードを DRY に保つためだけではなく、Router の操作を最適化します。 -上記を参照すると、 ``Router::connect()`` をルートを接続するために使えることがわかります。 このメソッドは ``/`` スコープがデフォルトです。スコープを作成しいくつかのルートを 接続するために、 ``scope()`` メソッドを使います。 :: @@ -717,6 +717,82 @@ SEO に親和性があるルーティング 拡張子が :doc:`/controllers/components/request-handling` で使われ、それによって コンテンツタイプに合わせた自動的なビューの切り替えを行います。 +.. _connecting-scoped-middleware: + +Connecting Scoped Middleware +---------------------------- + +While Middleware can be applied to your entire application, applying middleware +to specific routing scopes offers more flexibility, as you can apply middleware +only where it is needed allowing your middleware to not concern itself with +how/where it is being applied. + +Before middleware can be applied to a scope, it needs to be +registered into the route collection:: + + // in config/routes.php + use Cake\Http\Middleware\CsrfProtectionMiddleware; + use Cake\Http\Middleware\EncryptedCookieMiddleware; + + Router::scope('/', function ($routes) { + $routes->registerMiddleware('csrf', new CsrfProtectionMiddleware()); + $routes->registerMiddleware('cookies', new EncryptedCookiesMiddleware()); + }); + +Once registered, scoped middleware can be applied to specific +scopes:: + + $routes->scope('/cms', function ($routes) { + // Enable CSRF & cookies middleware + $routes->applyMiddleware('csrf', 'cookies'); + $routes->get('/articles/:action/*', ['controller' => 'Articles']) + }); + +In situations where you have nested scopes, inner scopes will inherit the +middleware applied in the containing scope:: + + $routes->scope('/api', function ($routes) { + $routes->applyMiddleware('ratelimit', 'auth.api'); + $routes->scope('/v1', function ($routes) { + $routes->applyMiddleware('v1compat'); + // Define routes here. + }); + }); + +In the above example, the routes defined in ``/v1`` will have 'ratelimit', +'auth.api', and 'v1compat' middleware applied. If you re-open a scope, the +middleware applied to routes in each scope will be isolated:: + + $routes->scope('/blog', function ($routes) { + $routes->applyMiddleware('auth'); + // Connect the authenticated actions for the blog here. + }); + $routes->scope('/blog', function ($routes) { + // Connect the public actions for the blog here. + }); + +In the above example, the two uses of the ``/blog`` scope do not share +middleware. However, both of these scopes will inherit middleware defined in +their enclosing scopes. + +Grouping Middleware +------------------- + +To help keep your route code :abbr:`DRY (Do not Repeat Yourself)` middleware can +be combined into groups. Once combined groups can be applied like middleware +can:: + + $routes->registerMiddleware('cookie', new EncryptedCookieMiddleware()); + $routes->registerMiddleware('auth', new AuthenticationMiddleware()); + $routes->registerMiddleware('csrf', new CsrfProtectionMiddleware()); + $routes->middlewareGroup('web', ['cookie', 'auth', 'csrf']); + + // Apply the group + $routes->applyMiddleware('web'); + +.. versionadded:: 3.5.0 + Scoped middleware & middleware groups were added in 3.5.0 + .. _resource-routes: RESTful なルートの作成 From 5c5808b9c3e1c064181e4f1dce7c4a9d7457120d Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Fri, 4 Aug 2017 01:29:06 +0900 Subject: [PATCH 07/17] [ja] #5096 copy en to ja --- ja/_static/img/middleware-request.png | Bin 0 -> 16954 bytes ja/_static/img/middleware-setup.png | Bin 0 -> 14914 bytes ja/controllers/middleware.rst | 71 +++++++++++++++++--------- 3 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 ja/_static/img/middleware-request.png create mode 100644 ja/_static/img/middleware-setup.png diff --git a/ja/_static/img/middleware-request.png b/ja/_static/img/middleware-request.png new file mode 100644 index 0000000000000000000000000000000000000000..7301b090339d4336c7fb804cb876438931d8638d GIT binary patch literal 16954 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 Rw0!^o002ovPDHLkV1g`^m9GE* literal 0 HcmV?d00001 diff --git a/ja/_static/img/middleware-setup.png b/ja/_static/img/middleware-setup.png new file mode 100644 index 0000000000000000000000000000000000000000..5e65f5c4990fcd0518544edde4b88dc972c6cfb8 GIT binary patch literal 14914 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

lKS2sO1sHTACOOwHFe#8=g# zpdhu@#FUAG>iHK;CUr)Jh|j-@3Kuo;2nGJSC!=?eE)t{_LX9Sxh=`8Xh_8ic#PV7H zYw8KOQv1cM-!m_GX`1C1eeX5D%13AZaQt2>qF|hyM#DxYgeW2oOmwhDR4@2GboXnF zpsRDg{GEBtib?-8U4E3$ZwYz(ucnue-&^<^`XcSdlAB|h54^v{ND=;cKzN|7@qH7CE*tt-Au1BqZvYtyn3Kl zB(vX}zP#+OyNRzUpZr%IlbQ0#r%9I|{cDfR>$~5ZJjB2HUzygCbS6nwQsYZ63DOWD zk=8``*`1qem;UN1@pW(7+h3v7X76wA&%69KyZ6D``>(#5clm)Ue-8bp{Q!Gf7U-8?&rmXm_U&-Y+eq{&1dcT|@aWhQ`(ib6uh}>xvStT-4F27MLzMpR@e0_yj z{HgY;>F3}4^FrR-H-fId7Enu^xj;6Fsqf8+6C3C|PBcbnb*Bg-sm$g;{;T|+{8m#_ zVLtz#`Akz=VSby*oL^pOx{%+)*OJ`ALMy9h4^-D0=sZfaMo46*LlM38vLrH6WR9#5 zwSH~;5n5Yo8=11utmTK+44$Z^_Ylz?AyT3^Zh+lFQi@c}MxY#~Ag3-`PWJ(#KSE1p zQ@7u*UY#_GtE7^&87+)~YO%ouhQ}2U5}A!}L~n^&J317TwA%WDn#eep0O%?RQBXuu z%;`m?qO&QQwLSF{8HiuAi;RrRAhbrs$a%d%&eUR(R+dr4i13Y;8(e2xTnHhd#oFq+ z2zE(^EQxxI<|M5;sNhoMkl2;@xg0`^7OMv%7!!l|J=9?|o0F2%qL$uykweig#?KWI z63LCYx^95cTM~rSXf{)!K2b{nd;g#-@^evymh2`vZZP6fZ&eUqtF>2-g!r^FQ7FQP z{HEVtKRc4udNrw1!5)t42m# zV*4S#%13EVl7;1MXj&e%obQokAkW#$m^UyuR4sN%=Q*AbTD@wmxO%8AGG|^5+pnr6 zs9q$>;Hzb_9wbd|65(jIJu)@1p0vKcB^0r{lrs=n7Z>f?;u}{8uM4tP99QC%H3ge)!& z{j07%5iJ(i%H_?(Gsf3@9%l$|q`__ で利用可能な、あらゆる PSR-7 互換の -ミドルウェアを使うことができます。 +ミドルウエアの視覚的なイメージとしては、あなたの作るアプリケーションは中央で完結していて、 +ミドルウェアはタマネギのようにアプリケーションの周囲を包み込むに囲っているものになります。 +この例では、Routes、Assets、Exception Handling、およびCORSヘッダーミドルウェアでラップされたアプリケーションを見て取れます。 -CakePHP はいくつかのミドルウェアを既成で提供します。 +.. image:: /_static/img/middleware-setup.png + +When a request is handled by your application it enters from the outermost +middleware. Each middleware can either delegate the request/response to the next +layer, or return a response. Returning a response prevents lower layers from +ever seeing the request. An example of that is the AssetMiddleware handling +a request for a plugin image during development. + +.. image:: /_static/img/middleware-request.png + +If no middleware take action to handle the request, a controller will be located +and have its action invoked, or an exception will be raised generating an error +page. + +Middleware are part of the new HTTP stack in CakePHP that leverages the PSR-7 +request and response interfaces. Because CakePHP is leveraging the PSR-7 +standard you can use any PSR-7 compatible middleware available on `The Packagist +`__. + +CakePHP にあるミドルウェア +========================== + +CakePHP はWebアプリケーションで一般的なタスクを取り扱うためのいくつかのミドルウェアを +提供します。 * ``Cake\Error\Middleware\ErrorHandlerMiddleware`` はラップされたミドルウェアからくる 例外を捕まえ、 :doc:`/development/errors` の例外ハンドラーを使ってエラーページを描画します。 @@ -30,10 +52,13 @@ CakePHP はいくつかのミドルウェアを既成で提供します。 ミドルウェアの使用 ================== -``App\Application`` クラスの ``middleware`` メソッドの中でミドルウェアを加えることができます。 -もし ``App\Application`` クラスを持っていない場合、詳しくは :ref:`adding-http-stack` -の当該のセクションを参照してください。アプリケーションの ``middleware`` フックメソッドは -リクエスト処理の中で早くに呼ばれて、 ``Middleware`` オブジェクトを加えることができます。 :: +ミドルウェアは、アプリケーションの全体、またはルーティングスコープ個別に適用できます + +すべてのリクエストにミドルウェアを適用するには、 ``App\Application`` クラスの +``middleware`` メソッドを使用します。 ``App\Application`` クラスを持っていなかった場合、 +:ref:`adding-http-stack` の該当のセクションを参照してください。 +アプリケーションの ``middleware`` フックメソッドはリクエスト処理の開始時に +呼ばれて ``MiddlewareQueue`` オブジェクトを加えることができます:: namespace App; @@ -42,11 +67,11 @@ CakePHP はいくつかのミドルウェアを既成で提供します。 class Application extends BaseApplication { - public function middleware($middlewareStack) + public function middleware($middlewareQueue) { - // ミドルウェアのキューにエラーハンドラーを結びつけます。 - $middlewareStack->add(new ErrorHandlerMiddleware()); - return $middlewareStack; + // Bind the error handler into the middleware queue. + $middlewareQueue->add(new ErrorHandlerMiddleware()); + return $middlewareQueue; } } @@ -55,19 +80,19 @@ CakePHP はいくつかのミドルウェアを既成で提供します。 $layer = new \App\Middleware\CustomMiddleware; // 追加されたミドルウェアは行列の末尾になります。 - $middlewareStack->add($layer); + $middlewareQueue->add($layer); // 追加されたミドルウェアは行列の先頭になります。 - $middlewareStack->prepend($layer); + $middlewareQueue->prepend($layer); // 特定の位置に挿入します。もし位置が範囲外の場合、 // 末尾に追加されます。 - $middlewareStack->insertAt(2, $layer); + $middlewareQueue->insertAt(2, $layer); // 別のミドルウェアの前に挿入します。 // もしその名前のクラスが見つからない場合、 // 例外が発生します。 - $middlewareStack->insertBefore( + $middlewareQueue->insertBefore( 'Cake\Error\Middleware\ErrorHandlerMiddleware', $layer ); @@ -75,7 +100,7 @@ CakePHP はいくつかのミドルウェアを既成で提供します。 // 別のミドルウェアの後に挿入します。 // もしその名前のクラスが見つからない場合、 // ミドルウェアは末尾に追加されます。 - $middlewareStack->insertAfter( + $middlewareQueue->insertAfter( 'Cake\Error\Middleware\ErrorHandlerMiddleware', $layer ); @@ -93,8 +118,8 @@ CakePHP はいくつかのミドルウェアを既成で提供します。 EventManager::instance()->on( 'Server.buildMiddleware', - function ($event, $middlewareStack) { - $middlewareStack->add(new ContactPluginMiddleware()); + function ($event, $middlewareQueueStack) { + $middlewareQueueStack->add(new ContactPluginMiddleware()); }); PSR-7 リクエストとレスポンス @@ -243,14 +268,14 @@ PSR-7 リクエストとレスポンス class Application { - public function middleware($middlewareStack) + public function middleware($middlewareQueueStack) { // 単純なミドルウェアをキューに追加します - $middlewareStack->add(new TrackingCookieMiddleware()); + $middlewareQueueStack->add(new TrackingCookieMiddleware()); // もう少しミドルウェアをキューに追加します - return $middlewareStack; + return $middlewareQueueStack; } } From e7b71287c1b67a6a6c8ea3c96d7cf83ce0ca4026 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 00:25:55 +0900 Subject: [PATCH 08/17] [ja] fix #4912 copy mistake --- ja/controllers/request-response.rst | 492 ++-------------------------- 1 file changed, 28 insertions(+), 464 deletions(-) diff --git a/ja/controllers/request-response.rst b/ja/controllers/request-response.rst index 34d97aa132..d5e8aee6b3 100644 --- a/ja/controllers/request-response.rst +++ b/ja/controllers/request-response.rst @@ -436,471 +436,7 @@ to work with cookie collection. .. index:: $this->response -Response -======== -.. php:class:: Response - -:php:class:`Cake\\Http\\Response` is the default response class in CakePHP. -It encapsulates a number of features and functionality for generating HTTP -responses in your application. It also assists in testing, as it can be -mocked/stubbed allowing you to inspect headers that will be sent. -Like :php:class:`Cake\\Http\\ServerRequest`, :php:class:`Cake\\Http\\Response` -consolidates a number of methods previously found on :php:class:`Controller`, -:php:class:`RequestHandlerComponent` and :php:class:`Dispatcher`. The old -methods are deprecated in favour of using :php:class:`Cake\\Http\\Response`. - -``Response`` provides an interface to wrap the common response-related -tasks such as: - -* Sending headers for redirects. -* Sending content type headers. -* Sending any header. -* Sending the response body. - -Dealing with Content Types --------------------------- - -.. php:method:: withType($contentType = null) - -You can control the Content-Type of your application's responses with -:php:meth:`Cake\\Http\\Response::withType()`. If your application needs to deal -with content types that are not built into Response, you can map them with -``type()`` as well:: - - // Add a vCard type - $this->response->type(['vcf' => 'text/v-card']); - - // Set the response Content-Type to vcard. - $this->response = $this->response->withType('vcf'); - - // Prior to 3.4.0 - $this->response->type('vcf'); - -Usually, you'll want to map additional content types in your controller's -:php:meth:`~Controller::beforeFilter()` callback, so you can leverage the -automatic view switching features of :php:class:`RequestHandlerComponent` if you -are using it. - -.. _cake-response-file: - -Sending Files -------------- - -.. php:method:: withFile($path, $options = []) - -There are times when you want to send files as responses for your requests. -You can accomplish that by using :php:meth:`Cake\\Http\\Response::withFile()`:: - - public function sendFile($id) - { - $file = $this->Attachments->getFile($id); - $response = $this->response->withFile($file['path']); - // Return the response to prevent controller from trying to render - // a view. - return $response; - } - - // Prior to 3.4.0 - $file = $this->Attachments->getFile($id); - $this->response->file($file['path']); - // Return the response to prevent controller from trying to render - // a view. - return $this->response; - -As shown in the above example, you must pass the file path to the method. -CakePHP will send a proper content type header if it's a known file type listed -in `Cake\\Http\\Reponse::$_mimeTypes`. You can add new types prior to calling -:php:meth:`Cake\\Http\\Response::withFile()` by using the -:php:meth:`Cake\\Http\\Response::withType()` method. - -If you want, you can also force a file to be downloaded instead of displayed in -the browser by specifying the options:: - - $response = $this->response->withFile( - $file['path'], - ['download' => true, 'name' => 'foo'] - ); - - // Prior to 3.4.0 - $this->response->file( - $file['path'], - ['download' => true, 'name' => 'foo'] - ); - -The supported options are: - -name - The name allows you to specify an alternate file name to be sent to - the user. -download - A boolean value indicating whether headers should be set to force - download. - -Sending a String as File ------------------------- - -You can respond with a file that does not exist on the disk, such as a pdf or an -ics generated on the fly from a string:: - - public function sendIcs() - { - $icsString = $this->Calendars->generateIcs(); - $response = $this->response; - $response->body($icsString); - - $response = $response->withType('ics'); - - // Optionally force file download - $response = $response->withDownload('filename_for_download.ics'); - - // Return response object to prevent controller from trying to render - // a view. - return $response; - } - -Callbacks can also return the body as a string:: - - $path = '/some/file.png'; - $this->response->body(function () use ($path) { - return file_get_contents($path); - }); - -Setting Headers ---------------- - -.. php:method:: withHeader($header, $value) - -Setting headers is done with the :php:meth:`Cake\\Http\\Response::withHeader()` -method. Like all of the PSR-7 interface methods, this method returns a *new* -instance with the new header:: - - // Add/replace a header - $response = $response->withHeader('X-Extra', 'My header'); - - // Set multiple headers - $response = $response->withHeader('X-Extra', 'My header') - ->withHeader('Location', 'http://example.com'); - - // Append a value to an existing header - $response = $response->withAddedHeader('Set-Cookie', 'remember_me=1'); - - // Prior to 3.4.0 - Set a header - $this->response->header('Location', 'http://example.com'); - -Headers are not sent when set. Instead, they are held until the response is -emitted by ``Cake\Http\Server``. - -You can now use the convenience method -:php:meth:`Cake\\Http\\Response::withLocation()` to directly set or get the -redirect location header. - -Setting the Body ----------------- - -.. php:method:: withStringBody($string) - -To set a string as the response body, do the following:: - - // Set a string into the body - $response = $response->withStringBody('My Body'); - - // If you want a json response - $response = $response->withType('application/json') - ->withStringBody(json_encode(['Foo' => 'bar'])); - -.. versionadded:: 3.4.3 - ``withStringBody()`` was added in 3.4.3 - -.. php:method:: withBody($body) - -To set the response body, use the ``withBody()`` method, which is provided by the -:php:class:`Zend\\Diactoros\\MessageTrait`:: - - $response = $response->withBody($stream); - - // Prior to 3.4.0 - Set the body - $this->response->body('My Body'); - -Be sure that ``$stream`` is a :php:class:`Psr\\Http\\Message\\StreamInterface` object. -See below on how to create a new stream. - -You can also stream responses from files using :php:class:`Zend\\Diactoros\\Stream` streams:: - - // To stream from a file - use Zend\Diactoros\Stream; - - $stream = new Stream('/path/to/file', 'rb'); - $response = $response->withBody($stream); - -You can also stream responses from a callback using the ``CallbackStream``. This -is useful when you have resources like images, CSV files or PDFs you need to -stream to the client:: - - // Streaming from a callback - use Cake\Http\CallbackStream; - - // Create an image. - $img = imagecreate(100, 100); - // ... - - $stream = new CallbackStream(function () use ($img) { - imagepng($img); - }); - $response = $response->withBody($stream); - - // Prior to 3.4.0 you can use the following to create streaming responses. - $file = fopen('/some/file.png', 'r'); - $this->response->body(function () use ($file) { - rewind($file); - fpassthru($file); - fclose($file); - }); - -Setting the Character Set -------------------------- - -.. php:method:: withCharset($charset) - -Sets the charset that will be used in the response:: - - $this->response = $this->response->withCharset('UTF-8'); - - // Prior to 3.4.0 - $this->response->charset('UTF-8'); - -Interacting with Browser Caching --------------------------------- - -.. php:method:: withDisabledCache() - -You sometimes need to force browsers not to cache the results of a controller -action. :php:meth:`Cake\\Http\\Response::withDisabledCache()` is intended for just -that:: - - public function index() - { - // Disable caching - $this->response = $this->response->withDisabledCache(); - } - -.. warning:: - - Disabling caching from SSL domains while trying to send - files to Internet Explorer can result in errors. - -.. php:method:: withCache($since, $time = '+1 day') - -You can also tell clients that you want them to cache responses. By using -:php:meth:`Cake\\Http\\Response::withCache()`:: - - public function index() - { - // Enable caching - $this->response = $this->response->withCache('-1 minute', '+5 days'); - } - -The above would tell clients to cache the resulting response for 5 days, -hopefully speeding up your visitors' experience. -The ``withCache()`` method sets the ``Last-Modified`` value to the first -argument. ``Expires`` header and the ``max-age`` directive are set based on the -second parameter. Cache-Control's ``public`` directive is set as well. - -.. _cake-response-caching: - -Fine Tuning HTTP Cache ----------------------- - -One of the best and easiest ways of speeding up your application is to use HTTP -cache. Under this caching model, you are only required to help clients decide if -they should use a cached copy of the response by setting a few headers such as -modified time and response entity tag. - -Rather than forcing you to code the logic for caching and for invalidating -(refreshing) it once the data has changed, HTTP uses two models, expiration and -validation, which usually are much simpler to use. - -Apart from using :php:meth:`Cake\\Http\\Response::withCache()`, you can also use -many other methods to fine-tune HTTP cache headers to take advantage of browser -or reverse proxy caching. - -The Cache Control Header -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. php:method:: withSharable($public, $time = null) - -Used under the expiration model, this header contains multiple indicators that -can change the way browsers or proxies use the cached content. A -``Cache-Control`` header can look like this:: - - Cache-Control: private, max-age=3600, must-revalidate - -``Response`` class helps you set this header with some utility methods that will -produce a final valid ``Cache-Control`` header. The first is the -``withSharable()`` method, which indicates whether a response is to be -considered sharable across different users or clients. This method actually -controls the ``public`` or ``private`` part of this header. Setting a response -as private indicates that all or part of it is intended for a single user. To -take advantage of shared caches, the control directive must be set as public. - -The second parameter of this method is used to specify a ``max-age`` for the -cache, which is the number of seconds after which the response is no longer -considered fresh:: - - public function view() - { - // ... - // Set the Cache-Control as public for 3600 seconds - $this->response = $this->response->withSharable(true, 3600); - } - - public function my_data() - { - // ... - // Set the Cache-Control as private for 3600 seconds - $this->response = $this->response->withSharable(false, 3600); - } - -``Response`` exposes separate methods for setting each of the directives in -the ``Cache-Control`` header. - -The Expiration Header -~~~~~~~~~~~~~~~~~~~~~ - -.. php:method:: withExpires($time) - -You can set the ``Expires`` header to a date and time after which the response -is no longer considered fresh. This header can be set using the -``withExpires()`` method:: - - public function view() - { - $this->response = $this->response->withExpires('+5 days'); - } - -This method also accepts a :php:class:`DateTime` instance or any string that can -be parsed by the :php:class:`DateTime` class. - -The Etag Header -~~~~~~~~~~~~~~~ - -.. php:method:: withEtag($tag, $weak = false) - -Cache validation in HTTP is often used when content is constantly changing, and -asks the application to only generate the response contents if the cache is no -longer fresh. Under this model, the client continues to store pages in the -cache, but it asks the application every time -whether the resource has changed, instead of using it directly. -This is commonly used with static resources such as images and other assets. - -The ``withEtag()`` method (called entity tag) is a string -that uniquely identifies the requested resource, as a checksum does for a file, -in order to determine whether it matches a cached resource. - -To take advantage of this header, you must either call the -``checkNotModified()`` method manually or include the -:doc:`/controllers/components/request-handling` in your controller:: - - public function index() - { - $articles = $this->Articles->find('all'); - $response = $this->response->withEtag($this->Articles->generateHash($articles)); - if ($response->checkNotModified($this->request)) { - return $response; - } - $this->response = $response; - // ... - } - -.. note:: - - Most proxy users should probably consider using the Last Modified Header - instead of Etags for performance and compatibility reasons. - -The Last Modified Header -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. php:method:: withModified($time) - -Also, under the HTTP cache validation model, you can set the ``Last-Modified`` -header to indicate the date and time at which the resource was modified for the -last time. Setting this header helps CakePHP tell caching clients whether the -response was modified or not based on their cache. - - -To take advantage of this header, you must either call the -``checkNotModified()`` method manually or include the -:doc:`/controllers/components/request-handling` in your controller:: - - public function view() - { - $article = $this->Articles->find()->first(); - $response = $this->response->withModified($article->modified); - if ($response->checkNotModified($this->request)) { - return $response; - } - $this->response; - // ... - } - -The Vary Header -~~~~~~~~~~~~~~~ - -.. php:method:: withVary($header) - -In some cases, you might want to serve different content using the same URL. -This is often the case if you have a multilingual page or respond with different -HTML depending on the browser. Under such circumstances you can use the ``Vary`` -header:: - - $response = $this->response->withVary('User-Agent'); - $response = $this->response->withVary('Accept-Encoding', 'User-Agent'); - $response = $this->response->withVary('Accept-Language'); - -Sending Not-Modified Responses -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. php:method:: checkNotModified(Request $request) - -Compares the cache headers for the request object with the cache header from the -response and determines whether it can still be considered fresh. If so, deletes -the response content, and sends the `304 Not Modified` header:: - - // In a controller action. - if ($this->response->checkNotModified($this->request)) { - return $this->response; - } - -.. _response-cookies: - -Setting Cookies -=============== - -Cookies can be added to response using either an array or a :php:class:`Cookie`` -object:: - - // Add a cookie as an array using the immutable API (3.4.0+) - $this->response = $this->response->withCookie('remember_me', [ - 'value' => 'yes', - 'path' => '/', - 'httpOnly' => true, - 'secure' => false, - 'expire' => strtotime('+1 year') - ]); - - // Before 3.4.0 - $this->response->cookie('remember', [ - 'value' => 'yes', - 'path' => '/', - 'httpOnly' => true, - 'secure' => false, - 'expire' => strtotime('+1 year') - ]); - -See the :ref:`creating-cookies` section for how to use the cookie object. - - -.. index:: $this->response レスポンス ========== @@ -1312,6 +848,34 @@ Not-Modified レスポンスの送信 return $this->response; } +.. _response-cookies: + +Setting Cookies +=============== + +Cookies can be added to response using either an array or a :php:class:`Cookie`` +object:: + + // Add a cookie as an array using the immutable API (3.4.0+) + $this->response = $this->response->withCookie('remember_me', [ + 'value' => 'yes', + 'path' => '/', + 'httpOnly' => true, + 'secure' => false, + 'expire' => strtotime('+1 year') + ]); + + // Before 3.4.0 + $this->response->cookie('remember', [ + 'value' => 'yes', + 'path' => '/', + 'httpOnly' => true, + 'secure' => false, + 'expire' => strtotime('+1 year') + ]); + +See the :ref:`creating-cookies` section for how to use the cookie object. + .. _cors-headers: クロスオリジンリクエストヘッダー(CORS)の設定 From f247d2d0b4549c254d855c178b969d87249f508b Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 00:40:41 +0900 Subject: [PATCH 09/17] [ja] #4904 copy from en to ja --- ja/controllers/middleware.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ja/controllers/middleware.rst b/ja/controllers/middleware.rst index 36c0e10fea..a4a462149f 100644 --- a/ja/controllers/middleware.rst +++ b/ja/controllers/middleware.rst @@ -41,6 +41,8 @@ CakePHP はWebアプリケーションで一般的なタスクを取り扱うた リクエストにルーティングパラメーターを割り当てるために ``Router`` を使用します。 * ``Cake\I18n\Middleware\LocaleSelectorMiddleware`` はブラウザーによって送られる ``Accept-Language`` ヘッダーによって自動で言語を切り替えられるようにします。 +* ``Cake\Http\Middleware\SecurityHeadersMiddleware`` makes it easy to add + security related headers like ``X-Frame-Options`` to responses. * ``Cake\Http\Middleware\EncryptedCookieMiddleware`` gives you the ability to manipulate encrypted cookies in case you need to manipulate cookie with obfuscated data. From b5358fe07b892531570e23d7c24f672a4baced8c Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 01:33:43 +0900 Subject: [PATCH 10/17] [ja] #5019 copy from en to ja --- ja/development/routing.rst | 218 +++++++++++++++++++++++++++++-------- 1 file changed, 172 insertions(+), 46 deletions(-) diff --git a/ja/development/routing.rst b/ja/development/routing.rst index 693edeea99..57599d6abd 100644 --- a/ja/development/routing.rst +++ b/ja/development/routing.rst @@ -47,6 +47,14 @@ index メソッドを実行します。時々、複数のパラメーターを アクセスを防ぐわけではありません。もし、あなたが望むなら、いくつかのパラメーターを正規表現に従うように 修正できます。 :: + $routes->connect( + '/articles/:id', + ['controller' => 'Articles', 'action' => 'view'], + ) + ->setPatterns(['id' => '\d+']) + ->setPass(['id']); + + // Prior to 3.5 use the options array $routes->connect( '/articles/:id', ['controller' => 'Articles', 'action' => 'view'], @@ -118,6 +126,7 @@ URL 文字列を生成できることを意味します。 :: use Cake\Routing\Route\DashedRoute; Router::scope('/', function ($routes) { + // Connect the generic fallback routes. $routes->fallbacks(DashedRoute::class); }); @@ -129,7 +138,7 @@ URL 文字列を生成できることを意味します。 :: ルートを定義するための基本のフォーマットは、次の通りです。 :: $routes->connect( - 'URL テンプレート', + 'url/template', ['default' => 'defaultValue'], ['option' => 'matchingRegex'] ); @@ -187,7 +196,7 @@ Router の別の一般的な使い方は、コントローラーの "エイリ '/cooks/:action/*', ['controller' => 'Users'] ); -これは Router に ``/cooks/`` で始まるすべての URL は users コントローラーに送るように +これは Router に ``/cooks/`` で始まるすべての URL は ``UsersController`` に送るように 伝えています。 アクションは ``:action`` パラメーターの値によって呼ばれるかどうか決まります。 :ref:`route-elements` を使って、ユーザーの入力や変数を受け付けるいろいろなルーティングが できます。上記のルーティングの方法は、貧欲なスター (greedy star) を使います。 @@ -198,6 +207,40 @@ URL を生成するときにもルーティングは使われます。もし最 ``['controller' => 'users', 'action' => 'some_action', 5]`` を使って ``/cooks/some_action/5`` と出力します。 +The routes we've connected so far will match any HTTP verb. If you are building +a REST API you'll often want to map HTTP actions to different controller methods. +The ``RouteBuilder`` provides helper methods that make defining routes for +specific HTTP verbs simpler:: + + // Create a route that only responds to GET requests. + $routes->get( + '/cooks/:id', + ['controller' => 'Users', 'action' => 'view'], + 'users:view' + ); + + // Create a route that only responds to PUT requests + $routes->put( + '/cooks/:id', + ['controller' => 'Users', 'action' => 'update'], + 'users:update' + ); + +The above routes map the same URL to different controller actions based on the +HTTP verb used. GET requests will go to the 'view' action, while PUT requests +will go to the 'update' action. There are HTTP helper methods for: + +* GET +* POST +* PUT +* PATCH +* DELETE +* OPTIONS +* HEAD + +All of these methods return the route instance allowing you to leverage the +:ref:`fluent setters ` to further configure your route. + .. _route-elements: ルート要素 @@ -210,6 +253,12 @@ URL のどこに配置すべきなのかを定義することができます。 これは CakePHP にどんな URL が正しいフォーマットなのかを伝えます。 正規表現を使用しなかった場合、 ``/`` 以外の文字はパラメーターの一部として扱われます。 :: + $routes->connect( + '/:controller/:id', + ['action' => 'view'] + )->setPatterns(['id' => '[0-9]+']); + + // Prior to 3.5 use the options array $routes->connect( '/:controller/:id', ['action' => 'view'], @@ -228,11 +277,19 @@ CakePHP は小文字とダッシュによって表された URL を ``:controlle use Cake\Routing\Route\DashedRoute; - $routes->connect( - '/:controller/:id', - ['action' => 'view'], - ['id' => '[0-9]+', 'routeClass' => DashedRoute::class] - ); + // Create a builder with a different route class. + $routes->scope('/', function ($routes) { + $routes->setRouteClass(DashedRoute::class); + $routes->connect('/:controller/:id', ['action' => 'view']) + ->setPatterns(['id' => '[0-9]+']); + + // Prior to 3.5 use options array + $routes->connect( + '/:controller/:id', + ['action' => 'view'], + ['id' => '[0-9]+'] + ); + }); ``DashedRoute`` クラス ``:controller`` を確認し、 ``:plugin`` パラメーターを正しく小文字とダッシュによって表します。 @@ -258,23 +315,23 @@ ApplesController の ``view()`` メソッドを呼びます。 ``view()`` メ もし、大文字小文字を区別しない URL を提供したい場合、正規表現インライン修飾子を使います。 :: + // 3.5以前ではsetPatterns()の代わりにオプション配列を用いていました $routes->connect( '/:userShortcut', ['controller' => 'Teachers', 'action' => 'profile', 1], - ['userShortcut' => '(?i:principal)'] - ); + )->setPatterns(['userShortcut' => '(?i:principal)']); もう一つ例を挙げます。これであなたはルーティングのプロです。 :: + // 3.5以前ではsetPatterns()の代わりにオプション配列を用いていました $routes->connect( '/:controller/:year/:month/:day', - ['action' => 'index'], - [ - 'year' => '[12][0-9]{3}', - 'month' => '0[1-9]|1[012]', - 'day' => '0[1-9]|[12][0-9]|3[01]' - ] - ); + ['action' => 'index'] + )->setPatterns([ + 'year' => '[12][0-9]{3}', + 'month' => '0[1-9]|1[012]', + 'day' => '0[1-9]|[12][0-9]|3[01]' + ]); これは、いっそう複雑になりますが、ルーティングがとても強力になったことを示しています。 この URL は4つのルート要素を持っています。1番目は、なじみがあります。デフォルトのルート要素で @@ -314,6 +371,44 @@ CakePHP には、いくつかの特別な意味を持つルート要素があり * ``_name`` ルートの名前。名前付きルートをセットアップするときに、 それを指定するためのキーとして使えます。 +.. _route-fluent-methods: + +Configuring Route Options +------------------------- + +There are a number of route options that can be set on each route. After +connecting a route you can use its fluent builder methods to further configure +the route. These methods replace many of the keys in the ``$options`` parameter +of ``connect()``:: + + $routes->connect( + '/:lang/articles/:slug', + ['controller' => 'Articles', 'action' => 'view'], + ) + // Allow GET and POST requests. + ->setMethods(['GET', 'POST']) + + // Only match on the blog subdomain. + ->setHost('blog.example.com') + + // Set the route elements that should be converted to passed arguments + ->setPass(['slug']) + + // Set the matching patterns for route elements + ->setPatterns([ + 'slug' => '[a-z0-9-_]+', + 'lang' => 'en|fr|es', + ]) + + // Also allow JSON file extensions + ->setExtenions(['json']) + + // Set lang to be a persistent parameter + ->setPersist(['lang']); + +.. versionadded:: 3.5.0 + Fluent builder methods were added in 3.5.0 + アクションへのパラメーター渡し ------------------------------ @@ -332,15 +427,15 @@ CakePHP には、いくつかの特別な意味を持つルート要素があり $routes->connect( '/blog/:id-:slug', // 例えば /blog/3-CakePHP_Rocks ['controller' => 'Blogs', 'action' => 'view'], - [ - // 関数に引数を渡すためのルーティングテンプレートの中で、ルート要素を定義します。 - // テンプレートの中で、ルート要素を定義します。 - // ":id" をアクション内の $articleId にマップします。 - 'pass' => ['id', 'slug'], - // `id` が一致するパターンを定義します。 - 'id' => '[0-9]+' - ] - ); + ) + // 関数に引数を渡すためのルーティングテンプレートの中で、ルート要素を定義します。 + // テンプレートの中で、ルート要素を定義します。 + // ":id" をアクション内の $articleId にマップします。 + ->setPass(['id', 'slug']) + // `id` が一致するパターンを定義します。 + ->setPatterns([ + 'id' => '[0-9]+', + ]); }); 今、リバースルーティング機能のおかげで、下記のように URL 配列を渡し、 @@ -380,8 +475,16 @@ CakePHP はルートに定義された URL をどのように整えるのかを ['_name' => 'login'] ); + // HTTPメソッドで固有のルートを命名する (3.5.0以降) + $routes->post( + '/logout', + ['controller' => 'Users', 'action' => 'logout'], + 'logout' + ); + + // 名前付きルートで URL の生成 - $url = Router::url(['_name' => 'login']); + $url = Router::url(['_name' => 'logout']); // クエリー文字列引数付きの // 名前付きルートで URL の生成 @@ -401,7 +504,7 @@ CakePHP は、各スコープで名前のプレフィックスを定義するこ Router::scope('/api', ['_namePrefix' => 'api:'], function ($routes) { // このルートの名前は `api:ping` になります。 - $routes->connect('/ping', ['controller' => 'Pings'], ['_name' => 'ping']); + $routes->get('/ping', ['controller' => 'Pings'], 'ping'); }); // ping ルートのための URL を生成 Router::url(['_name' => 'api:ping']); @@ -422,7 +525,7 @@ CakePHP は、各スコープで名前のプレフィックスを定義するこ Router::plugin('Contacts', ['_namePrefix' => 'contacts:'], function ($routes) { $routes->scope('/api', ['_namePrefix' => 'api:'], function ($routes) { // このルートの名前は `contacts:api:ping` になります。 - $routes->connect('/ping', ['controller' => 'Pings'], ['_name' => 'ping']); + $routes->get('/ping', ['controller' => 'Pings'], 'ping'); }); }); @@ -598,18 +701,35 @@ SEO に親和性があるルーティング 指定した HTTP メソッドとの照合 ------------------------------ -ルートは、 ``_method`` ルーティングキーを使用して指定した HTTP メソッドとマッチできます。 :: +ルートは、HTTP動詞へルパーを使用して指定した HTTP メソッドとマッチできます。 :: Router::scope('/', function($routes) { // このルートは POST リクエスト上でのみマッチします。 - $routes->connect( + $routes->post( '/reviews/start', - ['controller' => 'Reviews', 'action' => 'start', '_method' => 'POST'] + ['controller' => 'Reviews', 'action' => 'start'] ); + + // 複数HTTPメソッドとマッチさせる + // 3.5以前では $options['_method'] をメソッドにセットして使用します。 + $routes->connect( + '/reviews/start', + [ + 'controller' => 'Reviews', + 'action' => 'start', + ] + )->setMethods(['POST', 'PUT']); }); 配列を使うことで複数の HTTP メソッドとマッチできます。 ``_method`` パラメーターは ルーティングキーなので、 URL の解析と URL の生成の両方に使われます。 +メソッド固有のルートのURLを生成するには、URLを生成する際に ``_method`` キーを含む必要があります。:: + + $url = Router::url([ + 'controller' => 'Reviews', + 'action' => 'start', + '_method' => 'POST', + ]); 指定したホスト名との照合 ------------------------ @@ -619,18 +739,17 @@ SEO に親和性があるルーティング Router::scope('/', function($routes) { // このルートは http://images.example.com のみマッチします。 + // 3.5以前では_hostオプションを使用します。 $routes->connect( '/images/default-logo.png', - ['controller' => 'Images', 'action' => 'default'], - ['_host' => 'images.example.com'] - ); + ['controller' => 'Images', 'action' => 'default'] + )->setHost('images.example.com'); // このルートは http://*.example.com のみマッチします。 $routes->connect( '/images/old-log.png', - ['controller' => 'Images', 'action' => 'oldLogo'], - ['_host' => '*.example.com'] - ); + ['controller' => 'Images', 'action' => 'oldLogo'] + )->setHost('images.example.com'); }); ``_host`` オプションは URL 生成でも使用されます。 ``_host`` オプションで正確なドメインを @@ -640,15 +759,14 @@ SEO に親和性があるルーティング // このルートを持つ場合、 $routes->connect( '/images/old-log.png', - ['controller' => 'Images', 'action' => 'oldLogo'], - ['_host' => '*.example.com'] - ); + ['controller' => 'Images', 'action' => 'oldLogo'] + )->setHost('images.example.com'); // url を生成するために指定が必要です。 echo Router::url([ 'controller' => 'Images', 'action' => 'oldLogo', - '_host' => 'images.example.com' + '_host' => 'images.example.com', ]); .. versionadded:: 3.4.0 @@ -700,11 +818,8 @@ SEO に親和性があるルーティング $routes->extensions(['json', 'xml', 'html']); $routes->connect( '/:title', - ['controller' => 'Pages', 'action' => 'view'], - [ - 'pass' => ['title'] - ] - ); + ['controller' => 'Pages', 'action' => 'view'] + )->setPass(['title']); }); そして、ルートに対応するリンクを生成するために、以下のようにします。 :: @@ -1087,6 +1202,7 @@ URL を生成するときに、特別なルート要素が使用できます。 現在のスキーマにデフォルト設定されています。 * ``_host`` リンクのためのホストを設定します。デフォルトは、現在のホストです。 * ``_port`` 非標準なポートのリンクを作成するときにポートを設定します。 +* ``_method`` URLが存在するHTTPメソッドを定義します。 * ``_full`` ``true`` にすると、 ``FULL_BASE_URL`` 定数 が 生成された URL の前に加えられます。 * ``_ssl`` ``true`` にすると普通の URL から https に変換します。 @@ -1154,6 +1270,16 @@ URL を文字列で生成します。URL パラメーターがルートに一致 ['routeClass' => 'SlugRoute'] ); + // また、あなたのスコープ内にrouteClassを設定することもできます。 + $routes->scope('/', function ($routes) { + //Prior to 3.5.0 use `routeClass()` + $routes->setRouteClass('SlugRoute'); + $routes->connect( + '/:slug', + ['controller' => 'Articles', 'action' => 'view'] + ); + }); + このルートは ``SlugRoute`` のインスタンスを生成し、カスタムパラメーター処理を実装することができます。 標準的な :term:`プラグイン記法` を使ってプラグインルートクラスを使用できます。 From d294513e1d83a603a8b451955101180366287923 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 01:35:17 +0900 Subject: [PATCH 11/17] Fix semicolon was missing --- en/development/routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/development/routing.rst b/en/development/routing.rst index b85e521b47..73cc369eff 100644 --- a/en/development/routing.rst +++ b/en/development/routing.rst @@ -61,7 +61,7 @@ you wish, you can restrict some parameters to conform to a regular expression:: '/articles/:id', ['controller' => 'Articles', 'action' => 'view'], ['id' => '\d+', 'pass' => ['id']] - ) + ); The previous example changed the star matcher by a new placeholder ``:id``. Using placeholders allows us to validate parts of the URL, in this case we used From 7fd0775f646c74deedc475f6797d465a4ec171de Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 12:29:18 +0900 Subject: [PATCH 12/17] [ja] #5121 copy from en to ja --- ja/development/routing.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ja/development/routing.rst b/ja/development/routing.rst index 57599d6abd..526d44fa0f 100644 --- a/ja/development/routing.rst +++ b/ja/development/routing.rst @@ -789,15 +789,15 @@ SEO に親和性があるルーティング これは、スコープに関係なく、 **以後に** 接続された **全て** のルートに影響します。 -拡張子を特定のスコープに制限するために、 :php:meth:`Cake\\Routing\\RouteBuilder::extensions()` +拡張子を特定のスコープに制限するために、 :php:meth:`Cake\\Routing\\RouteBuilder::setExtensions()` メソッドを使用して定義することができます。 :: Router::scope('/', function ($routes) { - $routes->extensions(['json', 'xml']); - // ... + // 3.5.0 以前では `extensions()` を使用します。 + $routes->setExtensions(['json', 'xml']); }); -これは、 ``extensions()`` が呼ばれた **後の** スコープの中で接続されている +これは、 ``setExtensions()`` が呼ばれた **後の** スコープの中で接続されている 全てのルートのために名前付き拡張子を有効にします。それは、ネストされたスコープの中で 接続されているルートも含まれます。グローバルの :php:meth:`Router::extensions()` メソッドと 同様に、呼び出し前に接続されたルートは、拡張子を継承しません。 @@ -815,7 +815,7 @@ SEO に親和性があるルーティング 以下を使ってルートを設定します。 :: Router::scope('/page', function ($routes) { - $routes->extensions(['json', 'xml', 'html']); + $routes->setExtensions(['json', 'xml', 'html']); $routes->connect( '/:title', ['controller' => 'Pages', 'action' => 'view'] @@ -920,7 +920,7 @@ recipe コントローラーに REST アクセスできるようにしたい場 // config/routes.php 内で... Router::scope('/', function ($routes) { - $routes->extensions(['json']); + $routes->setExtensions(['json']); $routes->resources('Recipes'); }); @@ -1272,7 +1272,7 @@ URL を文字列で生成します。URL パラメーターがルートに一致 // また、あなたのスコープ内にrouteClassを設定することもできます。 $routes->scope('/', function ($routes) { - //Prior to 3.5.0 use `routeClass()` + // 3.5.0 以前では `routeClass()` を使用します。 $routes->setRouteClass('SlugRoute'); $routes->connect( '/:slug', From 7c9ca4ffa78f1b32e467d8cbe1ab1761ca42aec7 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 12:34:39 +0900 Subject: [PATCH 13/17] [ja] #5060 copy from en to ja --- ja/development/testing.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ja/development/testing.rst b/ja/development/testing.rst index b5385fbc48..297daf53f8 100644 --- a/ja/development/testing.rst +++ b/ja/development/testing.rst @@ -883,12 +883,17 @@ CakePHP は特殊な ``IntegrationTestCase`` クラスを提供しています * ``put()`` PUT リクエストを送信します。 * ``delete()`` DELETE リクエストを送信します。 * ``patch()`` PATCH リクエストを送信します。 +* ``options()`` OPTIONS リクエストを送信します。 +* ``head()`` HEAD リクエストを送信します。 ``get()`` と ``delete()`` を除く全てのメソッドは、あなたがリクエストボディーを送信することを 可能にする二番目のパラメーターを受け入れます。リクエストをディスパッチした後、あなたのリクエストに対して 正しく動作したことを確実にするために ``IntegrationTestCase`` や、PHPUnit が提供するさまざまな アサーションを使用することができます。 +.. versionadded:: 3.5.0 + ``options()`` と ``head()`` は 3.5.0 で追加されました。 + リクエストの設定 ---------------- @@ -1131,6 +1136,26 @@ JSON を返すコントローラーの簡単な例を示します。 :: CakePHP の組込み JsonView で、 ``debug`` が有効になっている場合、 ``JSON_PRETTY_PRINT`` オプションを使用します。 +Disabling Error Handling Middleware in Tests +-------------------------------------------- + +When debugging tests that are failing because your application is encountering +errors it can be helpful to temporarily disable the error handling middleware to +allow the underlying error to bubble up. You can use +``disableErrorHandlerMiddleware()`` to do this:: + + public function testGetMissing() + { + $this->disableErrorHandlerMiddleware(); + $this->get('/markers/not-there'); + $this->assertResponseCode(404); + } + +In the above example, the test would fail and the underlying exception message +and stack trace would be displayed instead of the rendered error page being +checked. + +.. versionadded:: 3.5.0 アサーションメソッド -------------------- From 7f1bd9a099bc60745d21d6e9d4c55a5ab0e1f77f Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sat, 2 Sep 2017 12:41:20 +0900 Subject: [PATCH 14/17] [ja] #5075, #5123 copy from en to ja --- ja/development/testing.rst | 280 +++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) diff --git a/ja/development/testing.rst b/ja/development/testing.rst index 297daf53f8..42fdfe854f 100644 --- a/ja/development/testing.rst +++ b/ja/development/testing.rst @@ -1282,6 +1282,286 @@ checked. # # modified: tests/comparisons/example.php +.. _console-integration-testing: + +Console Integration Testing +=========================== + +To make testing console applications easier, CakePHP comes with a +``ConsoleIntegrationTestCase`` class that can be used to test console applications +and assert against their results. + +.. versionadded:: 3.5.0 + + The ``ConsoleIntegrationTestCase`` was added. + +To get started testing your console application, create a test case that extends +``Cake\TestSuite\ConsoleIntegrationTestCase``. This class contains a method +``exec()`` that is used to execute your command. You can pass the same string +you would use in the CLI to this method. + +Let's start with a very simple shell, located in **src/Shell/MyConsoleShell.php**:: + + namespace App\Shell; + + use Cake\Console\ConsoleOptionParser; + use Cake\Console\Shell; + + class MyConsoleShell extends Shell + { + public function getOptionParser() + { + $parser = new ConsoleOptionParser(); + $parser->setDescription('My cool console app'); + + return $parser; + } + } + +To write an integration test for this shell, we would create a test case in +**tests/TestCase/Shell/MyConsoleShellTest.php** that extends +``Cake\TestSuite\ConsoleIntegrationTestCase``. This shell doesn't do much at the +moment, but let's just test that our shell's description is displayed in ``stdout``:: + + namespace App\Test\TestCase\Shell; + + use Cake\TestSuite\ConsoleIntegrationTestCase; + + class MyConsoleShellTest extends ConsoleIntegrationTestCase + { + public function testDescriptionOutput() + { + $this->exec('my_console'); + $this->assertOutputContains('My cool console app'); + } + } + +Our test passes! While this is very trivial example, it shows that creating an +integration test case for console applications is quite easy. Let's continue by +adding some subcommands and options to our shell:: + + namespace App\Shell; + + use Cake\Console\ConsoleOptionParser; + use Cake\I18n\FrozenTime; + + class MyConsoleShell extends Shell + { + public function getOptionParser() + { + $parser = new ConsoleOptionParser(); + + $updateModifiedParser = new ConsoleOptionParser(); + $updateModifiedParser->addArgument('table', [ + 'help' => 'Table to update', + 'required' => true + ]); + + $parser + ->setDescription('My cool console app') + ->addSubcommand('updateModified', [ + 'parser' => $updateModifiedParser + ]); + + return $parser; + } + + public function updateModified() + { + $table = $this->args[0]; + $this->loadModel($table); + $this->{$table}->query() + ->update() + ->set([ + 'modified' => new FrozenTime() + ]) + ->execute(); + } + } + +This is a more complete shell that has a subcommand with its own parser. Let's +test the ``updateModified`` subcommand. Modify your test case to the following +snippet of code:: + + namespace Cake\Test\TestCase\Shell; + + use Cake\Console\Shell; + use Cake\I18n\FrozenTime; + use Cake\ORM\TableRegistry; + use Cake\TestSuite\ConsoleIntegrationTestCase; + + class MyConsoleShellTest extends ConsoleIntegrationTestCase + { + + public $fixtures = [ + // assumes you have a UsersFixture + 'app.users' + ]; + + public function testDescriptionOutput() + { + $this->exec('my_console'); + $this->assertOutputContains('My cool console app'); + } + + public function testUpdateModified() + { + $now = new FrozenTime('2017-01-01 00:00:00'); + FrozenTime::setTestNow($now); + + $this->loadFixtures('Users'); + + $this->exec('my_console update_modified Users'); + $this->assertExitCode(Shell::CODE_SUCCESS); + + $user = TableRegistry::get('Users')->get(1); + $this->assertSame($user->modified->timestamp, $now->timestamp); + + FrozenTime::setTestNow(null); + } + } + +As you can see from the ``testUpdateModified`` method, we are testing that our +``update_modified`` subcommand updates the table that we are passing as the first +argument. First, we assert that the shell exited with the proper status code, +``0``. Then we check that our subcommand did its work, that is, updated the +table we provided and set the ``modified`` column to the current time. + +Remember, ``exec()`` will take the same string you type into your CLI, so you +can include options and arguments in your command string. + +Testing Interactive Shells +-------------------------- + +Consoles are often interactive. Testing interactive shells with the +``Cake\TestSuite\ConsoleIntegrationTestCase`` class only requires passing the +inputs you expect as the second parameter of ``exec()``. They should be +included as an array in the order that you expect them. + +Continuing with our example shell, let's add an interactive subcommand. Update +the shell class to the following:: + + namespace App\Shell; + + use Cake\Console\ConsoleOptionParser; + use Cake\Console\Shell; + use Cake\I18n\FrozenTime; + + class MyConsoleShell extends Shell + { + public function getOptionParser() + { + $parser = new ConsoleOptionParser(); + + $updateModifiedParser = new ConsoleOptionParser(); + $updateModifiedParser->addArgument('table', [ + 'help' => 'Table to update', + 'required' => true + ]); + + $parser + ->setDescription('My cool console app') + ->addSubcommand('updateModified', [ + 'parser' => $updateModifiedParser + ]) + // add a new subcommand + ->addSubcommand('bestFramework'); + + return $parser; + } + + public function updateModified() + { + $table = $this->args[0]; + $this->loadModel($table); + $this->{$table}->query() + ->update() + ->set([ + 'modified' => new FrozenTime() + ]) + ->execute(); + } + + // create this interactive subcommand + public function bestFramework() + { + $this->out('Hi there!'); + + $framework = $this->in('What is the best PHP framework?'); + if ($framework !== 'CakePHP') { + $this->err("I disagree that '$framework' is the best."); + $this->_stop(Shell::CODE_ERROR); + } + + $this->out('I agree!'); + } + } + +Now that we have an interactive subcommand, we can add a test case that tests +that we receive the proper response, and one that tests that we receive an +incorrect response. Add the following methods to +**tests/TestCase/Shell/MyConsoleShellTest.php**:: + + public function testBestFramework() + { + $this->exec('my_console best_framework', [ + 'CakePHP' + ]); + $this->assertExitCode(Shell::CODE_SUCCESS); + $this->assertOutputContains('I agree!'); + } + + public function testBestFrameworkWrongAnswer() + { + $this->exec('my_console best_framework', [ + 'my homemade framework' + ]); + $this->assertExitCode(Shell::CODE_ERROR); + $this->assertErrorRegExp("/I disagree that \'(.+)\' is the best\./"); + } + +As you can see from the ``testBestFramework``, it responds to the first input +request with "CakePHP". Since this is the correct answer according to our +subcommand, the shell will exit successfully after outputting a response. + +The second test case, ``testBestFrameworkWrongAnswer``, provides an incorrect +answer which causes our shell to fail and exit with ``1``. We also assert +that ``stderr`` was given our error, which includes the name of the incorrect +answer. + +Testing the CommandRunner +------------------------- + +To test shells that are dispatched using the ``CommandRunner`` class, enable it +in your test case with the following method:: + + $this->useCommandRunner(); + +.. versionadded:: 3.5.0 + + The ``CommandRunner`` class was added. + +Assertion methods +----------------- + +The ``Cake\TestSuite\ConsoleIntegrationTestCase`` class provides a number of +assertion methods that make it easy to assert against console output:: + + // assert that the shell exited with the expected code + $this->assertExitCode($expected); + + // assert that stdout contains a string + $this->assertOutputContains($expected); + + // assert that stderr contains a string + $this->assertErrorContains($expected); + + // assert that stdout matches a regular expression + $this->assertOutputRegExp($expected); + + // assert that stderr matches a regular expression + $this->assertErrorRegExp($expected); + ビューのテスト ============== From b1d3d663cb043ce7b36ced7f79ed89161ebb2724 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Mon, 11 Sep 2017 03:37:42 +0900 Subject: [PATCH 15/17] [ja] reflect latest 3-5-migration-guide.rst --- ja/appendices/3-5-migration-guide.rst | 50 ++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/ja/appendices/3-5-migration-guide.rst b/ja/appendices/3-5-migration-guide.rst index fe8f0bcb04..e5eb3db1ec 100644 --- a/ja/appendices/3-5-migration-guide.rst +++ b/ja/appendices/3-5-migration-guide.rst @@ -26,6 +26,12 @@ CakePHP 3.5 は、3.4 の API の完全上位互換です。 ``Cake\Database\TableSchemaAwareInterface`` を使用してください。 * ``Cake\Console\ShellDispatcher`` は非推奨です。アプリケーションでは ``Cake\Console\CommandRunner`` を代わりに使用するように更新してください。 +* ``Cake\Database\Schema\TableSchema::column()`` は非推奨です。 + 代わりに ``Cake\Database\Schema\TableSchema::getColumn()`` を使用してください。 +* ``Cake\Database\Schema\TableSchema::constraint()`` は非推奨です。 + 代わりに ``Cake\Database\Schema\TableSchema::getConstraint()`` を使用してください。 +* ``Cake\Database\Schema\TableSchema::index()`` は非推奨です。 + 代わりに ``Cake\Database\Schema\TableSchema::getIndex()`` を使用してください。 非推奨の複合 get / set メソッド ------------------------------- @@ -50,16 +56,22 @@ set メソッドに分割されています。 * ``outputAs()`` ``Cake\Database\Connection`` * ``logger()`` -``Cake\Datasource\TypedResultTrait`` +``Cake\Database\TypedResultInterface`` + * ``returnType()`` +``Cake\Database\TypedResultTrait`` * ``returnType()`` ``Cake\Database\Log\LoggingStatement`` * ``logger()`` ``Cake\Datasource\ModelAwareTrait`` * ``modelType()`` ``Cake\Database\Query`` - * ``valueBinder()`` (今は ``getValueBinder()``) + * ``valueBinder()`` の getter 部分 (今は ``getValueBinder()``) +``Cake\Database\Schema\TableSchema`` + * ``columnType()`` ``Cake\Datasource\QueryTrait`` - * ``eagerLoaded()`` (今は ``isEagerLoaded()``) + * ``eagerLoaded()`` の getter 部分 (今は ``isEagerLoaded()``) +``Cake\Event\EventDispatcherInterface`` + * ``eventManager()`` ``Cake\Event\EventDispatcherTrait`` * ``eventManager()`` ``Cake\Error\Debugger`` @@ -70,6 +82,10 @@ set メソッドに分割されています。 ``Cake\I18n\I18n`` * ``locale()`` * ``translator()`` + * ``defaultLocale()`` + * ``defaultFormatter()`` +``Cake\ORM\Association\BelongsToMany`` + * ``sort()`` ``Cake\ORM\LocatorAwareTrait`` * ``tableLocator()`` ``Cake\ORM\EntityTrait`` @@ -174,6 +190,13 @@ set メソッドに分割されています。 フォールバックを使用する構成を定義するものです。 詳しくは :ref:`cache-configuration-fallback` のフォールバックの設定をご覧ください。 +アプリケーションのスケルトンに dotenv のサーポートを追加 +-------------------------------------------------------- + +アプリケーションのスケルトンに、「dotenv」の統合機能が追加されました。 +これは、あなたのアプリケーションを環境変数を使用して構成することを容易にします。 +詳しくは :ref:`environment-variables` の章をご覧ください。 + コンソールの結合テスト ---------------------- @@ -183,6 +206,13 @@ set メソッドに分割されています。 このテストクラスは、現在の ``Cake\Console\ShellDispatcher`` および 新たに追加された ``Cake\Console\CommandRunner`` と完全に互換性があります。 +コレクション +------------ + +* ``Cake\Collection\Collection::avg()`` が追加されました。 +* ``Cake\Collection\Collection::median()`` が追加されました。 + + コア ---- @@ -246,6 +276,13 @@ Http * ``Cake\Http\Client::addCookie()`` が追加されました。 これはクライアントインスタンスへのクッキー追加を容易にします。 +インスタンス設定トレイト +------------------------ + +* ``InstanceConfigTrait::getConfig()`` は ``$default`` という + 第二引数を取るようになりました。もし特定の ``key`` に使用できる値がない場合、 + その ``$default`` の値が返却されます。 + ORM --- @@ -273,6 +310,8 @@ ORM TestSuite --------- +* ``TestCase::loadFixtures()`` は引数が与えられていないとき、 + すべてのフィクスチャーをロードするようになりました。 * ``IntegrationTestCase::head()`` が追加されました。 * ``IntegrationTestCase::options()`` が追加されました。 * ``IntegrationTestCase::disableErrorHandlerMiddleware()`` が追加されました。 @@ -280,8 +319,11 @@ TestSuite バリデーション -------------- + +* 非整数の値を取得できないようにするため、 + ``Cake\Validation\Validator::scalar()`` が追加されました。 * ``Cake\Validation\Validator::regex()`` が追加されました。 - これは正規表現パターンでデータ検証を今までより便利に行う方法です。 + 正規表現パターンでのデータ検証を今までより便利にします。 * ``Cake\Validation\Validator::addDefaultProvider()`` が追加されました。 このメソッドでアプリケーションで作成されたすべてのバリデーターに バリデーションプロバイダーを挿入できます。 From fcee1995d003596c163457292b698624863166cf Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Mon, 11 Sep 2017 03:42:08 +0900 Subject: [PATCH 16/17] [ja] fixed review content --- ja/appendices/3-5-migration-guide.rst | 2 +- ja/controllers/middleware.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ja/appendices/3-5-migration-guide.rst b/ja/appendices/3-5-migration-guide.rst index e5eb3db1ec..170b6ee1ca 100644 --- a/ja/appendices/3-5-migration-guide.rst +++ b/ja/appendices/3-5-migration-guide.rst @@ -19,7 +19,7 @@ CakePHP 3.5 は、3.4 の API の完全上位互換です。 * ``Cake\Http\Client\CookieCollection`` は非推奨です。 代わりに ``Cake\Http\Cookie\CookieCollection`` を使用してください。 * ``Cake\View\Helper\RssHelper`` は非推奨です。 - まれ利用されることがあるためRssHelperは非推奨となっています。 + 使用されることがまれなため、RssHelperは非推奨です。 * ``Cake\Controller\Component\CsrfComponent`` は非推奨です。 代わりに :ref:`csrf-middleware` を使用してください。 * ``Cake\Datasource\TableSchemaInterface`` は非推奨です。 diff --git a/ja/controllers/middleware.rst b/ja/controllers/middleware.rst index a4a462149f..da7f6b09fa 100644 --- a/ja/controllers/middleware.rst +++ b/ja/controllers/middleware.rst @@ -3,9 +3,9 @@ ミドルウェアオブジェクトは、再利用可能で構成可能なリクエスト処理、あるいは レスポンス構築処理の層でアプリケーションを‘ラップ’する機能を提供します。 -ミドルウエアの視覚的なイメージとしては、あなたの作るアプリケーションは中央で完結していて、 -ミドルウェアはタマネギのようにアプリケーションの周囲を包み込むに囲っているものになります。 -この例では、Routes、Assets、Exception Handling、およびCORSヘッダーミドルウェアでラップされたアプリケーションを見て取れます。 +視覚的には、アプリケーションは中央で終了し、ミドルウェアはタマネギのように +アプリの周囲を包み込みます。この例では、Routes、Assets、Exception Handling、 +およびCORSヘッダーミドルウェアでラップされたアプリケーションを見て取れます。 .. image:: /_static/img/middleware-setup.png @@ -71,7 +71,7 @@ CakePHP はWebアプリケーションで一般的なタスクを取り扱うた { public function middleware($middlewareQueue) { - // Bind the error handler into the middleware queue. + // ミドルウェアのキューにエラーハンドラーを結びつけます。 $middlewareQueue->add(new ErrorHandlerMiddleware()); return $middlewareQueue; } From a8361c648bfe85aea8609ec29f42b8e173c13d71 Mon Sep 17 00:00:00 2001 From: ryoichi-u Date: Sun, 17 Sep 2017 20:25:42 +0900 Subject: [PATCH 17/17] [ja] fixed review content - https://github.com/cakephp/docs/pull/5134#pullrequestreview-62018883 --- en/appendices/3-5-migration-guide.rst | 2 +- ja/appendices/3-5-migration-guide.rst | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/en/appendices/3-5-migration-guide.rst b/en/appendices/3-5-migration-guide.rst index c277760e0d..4a2a54ae82 100644 --- a/en/appendices/3-5-migration-guide.rst +++ b/en/appendices/3-5-migration-guide.rst @@ -196,7 +196,7 @@ Console Integration Testing The ``Cake\TestSuite\ConsoleIntegrationTestCase`` class was added to make integration testing console applications easier. For more information, visit the :ref:`console-integration-testing` section. This test class is fully -compatible with the current shell dispatcher as well as the new +compatible with the current ``Cake\Console\ShellDispatcher`` as well as the new ``Cake\Console\CommandRunner``. Collection diff --git a/ja/appendices/3-5-migration-guide.rst b/ja/appendices/3-5-migration-guide.rst index 170b6ee1ca..84b7a03bff 100644 --- a/ja/appendices/3-5-migration-guide.rst +++ b/ja/appendices/3-5-migration-guide.rst @@ -136,13 +136,13 @@ set メソッドに分割されています。 ``cookie()`` の結果を使用しなくなりました。代わりに ``Cookie`` ヘッダーと ``CookieCollection`` が使用できます。 これは、クライアントにカスタムHTTPアダプターを使用しているときにのみ影響があります。 -* シェルを呼び出すときにサブコマンドに複数文字を用いる場合、 +* シェルを呼び出すときにサブコマンドに複数ワードを用いる場合、 名前にはキャメルケースを使用する必要がありました。これからは アンダースコアでサブコマンドを呼び出すことができます。例えば、 ``cake tool initMyDb`` は ``cake tool init_my_db`` と呼び出すことができます。 あなたのシェルが変換規則の異なる2つのサブコマンドを用いていた場合は 最後に関連付けた規則のコマンドだけが機能します。 -* ``SecurityComponent`` はリクエストデータを持たないPOSTリクエストを捕獲します。 +* ``SecurityComponent`` はリクエストデータを持たないPOSTリクエストを破棄します。 この変更はデータベースのデフォルト値のみを使用してレコードを作成するアクションを 保護するのに役立ちます。 * ``Cake\ORM\Table::addBehavior()`` と ``removeBehavior()`` は ``$this`` を @@ -150,8 +150,7 @@ set メソッドに分割されています。 流れるようなインターフェイスで定義するのに便利です。 * キャッシュエンジンは失敗または誤って構成されたときに例外を発生させなくなりました。 代わりに、操作不能な ``NullEngine`` としてフォールバックさせます。フォールバックは - エンジンごとに定義することができます。 - 詳しくは、 :ref:`configured ` をご覧ください + エンジンごとに :ref:`設定 ` することもできます。 * ``Cake\Database\Type\DateTimeType`` は以前からのフォーマットに加えて ISO-8859-1 でフォーマットされた日付文字列(例えば、 2017-07-09T12:33:00+00:02) を 変換するようになりました。DateTimeTypeのサブクラスを作成している場合は @@ -250,8 +249,8 @@ set メソッドに分割されています。 ``PaginatorComponent`` は、このインターフェイスを通してページネーションを 取り扱うようになりました。これにより、他のORMと似た実装で コンポーネントによってページネーションをできるようになりました。 -* ``Cake\Datasource\Paginator`` を追加して ``ORM/Database/QueryInstances`` を - ページネーションできるようにしました。 +* ``Cake\Datasource\Paginator`` は ORM/Database のクエリーインスタンスを + ページ制御するために追加されました。 イベント -------- @@ -289,8 +288,8 @@ ORM * ``Cake\ORM\Query::contain()`` は一つのアソシエーションが入る場合、 ラッピング配列なしで呼び出すことができるようになり。つまり、 ``contain('Comments', function (){ ... });`` で動作するようになります。 - この変更で ``leftJoinWith()`` や ``matching()`` のような、他のeagerloading関連の - メソッドと ``contain()`` の一貫性を与えています。 + この変更で ``leftJoinWith()`` や ``matching()`` のような、他の + イーガーローディング関連のメソッドと ``contain()`` の一貫性を与えています。 ルーティング ------------ @@ -320,8 +319,8 @@ TestSuite バリデーション -------------- -* 非整数の値を取得できないようにするため、 - ``Cake\Validation\Validator::scalar()`` が追加されました。 +* ``Cake\Validation\Validator::scalar()`` は、フィールドが非スカラー型データを + 取得しないことを保証するために追加されました。 * ``Cake\Validation\Validator::regex()`` が追加されました。 正規表現パターンでのデータ検証を今までより便利にします。 * ``Cake\Validation\Validator::addDefaultProvider()`` が追加されました。