symfonyのフロントコントローラーをカスタマイズして、ファイル名の規則などをCakePHP風に


Twitterにて、@yuzoneさんが以下のようなことをつぶやいていました。

SymfonyはController名がぜんぶactions.class.phpっぽいので、間違えて違うのを編集しないように注意しないとなー
http://twitter.com/yuzone/status/12111530758


これについて、基本的にはアクション(Cakeでいうコントローラー)のファイル名は決められたものしか使えない(通常はactions.class.php)のですが、フロントコントローラーを拡張すると、独自の命名規則を使うことができます。

以下、ちょっとだけCake風のファイル名で扱うための変更手順です。

1. 独自フロントウェブコントローラーを作成

symfonyのフロントウェブコントローラーとは、CakePHPでいうControllerクラスの仕事の一部を担うもので、個別のアクションへの振り分けなどを行います。この部分をカスタマイズします。

/apps/frontend/libディレクトリに「myFrontWebController.class.php」ファイルを以下の内容で作成します。

<?php
class myFrontWebController extends sfFrontWebController
{
  protected function controllerExists($moduleName, $controllerName, $extension, $throwExceptions)
  {
    $dirs = $this->context->getConfiguration()->getControllerDirs($moduleName);
    foreach ($dirs as $dir => $checkEnabled)
    {
      $classSuffix = ucfirst(strtolower($extension));
      $file        = $dir.'/'.$moduleName.'_controller.php';  // ★1
      if (is_readable($file))
      {
        // action class exists
        require_once($file);

        //  ★2
        $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix] = $moduleName.'Controller';

        return true;
      }
    }

    // send an exception if debug
    if ($throwExceptions && sfConfig::get('sf_debug'))
    {
      $dirs = array_map(array('sfDebug', 'shortenFilePath'), array_keys($dirs));

      throw new sfControllerException(sprintf('Controller "%s/%s" does not exist in: %s.', $moduleName, $controllerName, implode(', ', $dirs)));
    }

    return false;
  }
}

ソース内の★1、★2の箇所が変更のポイントです。

  • ★1 : ファイル名を「モジュール名_controller.php」としています。モジュール名の大文字小文字はそのまま。
  • ★2 : クラス名を「モジュール名Controller」としています。モジュール名の大文字小文字はそのまま。

大文字小文字の規則もCake風にしたければ、適宜ucfirst()などを使えばよいですね。


2. 独自フロントウェブコントローラーを使うようにアプリケーションを設定

フロントウェブコントローラーなどは、symfonyのファクトリー設定で変更できます。
/apps/frontend/config/factories.ymlの末尾に以下の設定を追加します。

  controller:
    class: myFrontWebController

この後、symfony ccを実行してキャッシュをクリアします。

3. アクションファイルの名称を変更

例えば、以下のようにモジュールを作成したとします。

php symfony generate:module frontend posts

/apps/frontend/modules/posts/actionsディレクトリに「actions.class.php」が作成されますが、このファイルを「posts_controller.php」というファイル名に変更し、ファイルの中身のクラス名を「postsController」に変更します。



これで、少しだけCakePHP風のファイル名、クラス名になります。
ただし、モジュール生成コマンドなどで生成されるファイル名は以前のままなので、毎回手作業で変更しないといけませんが・・・・。

あとはアクションのメソッド名やテンプレートファイル名なども変更すると、さらにCakeっぽくできるでしょうけど、それはまたの機会に・・・。



P.S.
こんなこともできますよ程度ってことで・・・。こんな内容のエントリをid:brtRiverさんが書いていたような気がしなくもないのですが、思い出せず(涙)


4/14 14:24追記
ここに書いた方法は、symfonyのコアのソースコードを書き換えるのではなく、「通常の方法」でカスタマイズしている、という点は強調しておきます。
(コアのソースを書き換えればなんでもアリですが・・・)