1.3は以前使ってましたけど2.xは初めて。
だいぶ勝手が違っててちょっと戸惑いつつ、1.3よりさらに酷くなったドキュメントの物足りなさをこーどを解析して補いつつ…。
加えて、今回初めて Prefix Routing にチャレンジ中。
最初は管理画面と公開画面のController、Viewをフォルダ分けしようとカスタマイズもしてみたのだけど、 やっぱりCake的には邪道なのだろうと思い直し、標準のPrefix Routingを使うことに。…まあチャレンジってほどのことじゃないんだけども(^^;
ところが、どうもHelper系のURL生成の挙動がおかしい…。
Google先生に聞いてみると、どうも1.x時代からおかしな挙動をしているようで、困ってる方がたくさん…。
具体的に言うと、
たとえば、/prefix/controller/action のViewで newaction へのリンクを、ヘルパーで
$this->Html->url(‘action’ => ‘newaction’)
$this->Form->create(‘Model’, array(‘action’ => ‘newaction’)
$this->Paginator->next(‘next >>’)
のように生成しようとすると、リンク先が
/controller/prefix_newaction
となってしまう。
強引に /prefix/controller/newaction と指定することもできるけど、それじゃせっかくのヘルパーの意味が無い。
まさかこんな片手落ちな仕様なわけないだろうし、もし仕様ならカスタマイズしてやれ!
…ってことでコードを解析しました。
で、問題の箇所を特定。
まあこれはケアレスミス&テスト漏れって感じですね。
問題の箇所は、lib/Cake/Routing/Router.php の 801行目と844行目(CakePHP 2.2.2の場合)の2カ所です。
これはRouter::url()という、各ヘルパーがURLを生成する際にコールされているメソッドの中。ヘルパーメソッドのオプションやリクエストパラメータからURLを生成する処理を担っているメソッドです。
上記2カ所に、
$params[$prefix]
という記述があります。
$params は Requestオブジェクトのparams配列のコピー、$prefix は prefix の文字列です。 …とここで詳しい方はもうおわかりですね。
そうです。
Requestのparamsにはprefixをキーにした要素はありません(^^;
というわけで、これは
$params[‘prefix’]
の誤りです。
修正すると見違えるように完璧に動作します!
【2012.9.29 修正・追記】
次のように修正すると見違えるように完璧に動作します!
1 2 3 4 5 |
$prefixExists = (array_intersect_key($url, array_flip(self::$_prefixes))); foreach (self::$_prefixes as $prefix) { if (!empty($params['prefix']) && $params['prefix'] == $prefix && !$prefixExists) { $url[$prefix] = true; } elseif (isset($url[$prefix]) && !$url[$prefix]) { |
1 2 3 4 5 |
} else { foreach (self::$_prefixes as $prefix) { if (isset($params['prefix']) && $params['prefix'] == $prefix) { $output .= $prefix . '/'; break; |
以下、差分パッチです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# This patch file was generated by NetBeans IDE # It uses platform neutral UTF-8 encoding and \n newlines. --- lib/Cake/Routing/Router.php.orig +++ lib/Cake/Routing/Router.php @@ -798,7 +798,7 @@ $prefixExists = (array_intersect_key($url, array_flip(self::$_prefixes))); foreach (self::$_prefixes as $prefix) { - if (!empty($params[$prefix]) && !$prefixExists) { + if (!empty($params['prefix']) && $params['prefix'] == $prefix && !$prefixExists) { $url[$prefix] = true; } elseif (isset($url[$prefix]) && !$url[$prefix]) { unset($url[$prefix]); @@ -841,7 +841,7 @@ $output = substr($url, 1); } else { foreach (self::$_prefixes as $prefix) { - if (isset($params[$prefix])) { + if (isset($params['prefix']) && $params['prefix'] == $prefix) { $output .= $prefix . '/'; break; } |