CakePHP1.3系アプリのCakePHP2.0-alphaへの移行という茨の道を俺たちは登り始めたばかりだ

表題の通りすでに動いている既存のCakePHP1.3系アプリのCakePHP2.0-alphaへの移行を試しにやってみた。他にもこの茨の道を登り始めた人情報くれくれ。

追記:
CakePHP2.0へのmigrationツールの作成も行われてるらしいよ。これ動かしただけでは絶対に動かないと思うけどw
https://github.com/cakephp/cakephp/blob/2.0/lib/Cake/Console/Command/UpgradeShell.php

@cakephperさん情報ありがとうございました。
:追記終了

移行に際してはCakePHPの公式資料である2-0-migration-guideを参考にする。あとはソースを読む。フォースを感じる。などといった手段を取った。

ちなみに、簡単なアプリで試しただけなので、はまりポイントは他にも多々あると思われる。
また、僕のところではCakePHP+Smartyという茨の道を歩んでいるのでその点での修正点もある。

他にも移行ポイントがあったらこの記事に追記していく。
読めばわかると思うが、CakePHPに下位互換性なんてなかった。そんなものはなかったんや。夢。

ディレクトリ構成やファイル名の変更

ディレクトリ構成が変わってしまったので、以下のコマンドを実行する。
configからConfigに変更とかWindowsVM見えるようにしてたのではまった。Windowsとか窓から捨てたい。

mv config Config
mv Config/schema/ Config/Schema/
mv controllers/ Controller/
mv Controller/components Controller/Component
mv libs/ Lib
mv locale/ Locale/
mv models/ Model/
mv Model/behaviors/ Model/Behavior/
mv Model/datasources/ Model/Datasource/
mv plugins/ Plugin/
mv tests/ Test/
mv Test/fixtures/ Test/Fixture/
mv Test/cases/ Test/Case/
mv vendors/ Vendor/
mv views/ View/
mv View/elements/ View/Elements/
mv View/errors/ View/Errors/
mv View/helpers/ View/Helper/
mv View/layouts/ View/Layouts/
mv View/pages/ View/Pages/

修正しなくても動くが、全体的に、hoges_controller.phpが、推奨は HogesController.php になったようなので変更する。
全般的に、Snake Case だったのが Camel Case になったようだ。

僕んとこでは共通ファイルをcommon というところにつっこんでいたんだけど、app_controller.php という名前でおいていたんだが、app_controller.php というファイルより先に、Cakeが最初から持っている AppController.php を探しに行ってはまったので、ファイル名は変更しておいたほうがいい。

当然、自分で以下のように App::build とかで controller の場所とか足してた部分もこのネーミングルールに合わせる

   App::build(array(
              'plugins' => 'path/to/myplugins',
              'models' => 'path/to/mymodels'));

   App::build(array(
              'Plugin' => 'path/to/MyPlugins',
              'Model' => 'path/to/MyModels'));

VIEWSとかLIBSとかの define が無くなった。

VIEWSとかLIBSとかの define がカジュアルに無くなりました。
ちゃんと調べてないけど、ELEMENTSとかのdefineも多分なくなった。
カジュアルに。

だから代わりに、自分でVIEWSで実装してた部分を App. 'VIew' と書き換えましょう。

database.php の書き方

database.phpの書き方が以前は

'driver' => 'mysql'

だったのが、

'datasource' => 'Database/Mysql'

という書き方になったので修正

Component の変更

今まで親クラスを指定しなくても動いていたが、Componentを親クラスにしないと動かなくなった。もしかしたら、継承しなくても必要なメソッドを定義すればいいだけかもしれないが、試していない。

controller の $view ってのが $viewClass になった

controller 内の $view を $viewClass に変更する

controller の modelNames ってのがなくなった

$use をそのままつかうか、modelClass という変数を使うようにする

request の扱いの変更

CakeRequestというクラスが導入されてこっちが推奨になったっぽい。なので、今までの controller での

$this->params['hoge'];

というコードは

$this->request['hoge'];

にするのが良いっぽい(変えなくても動くけど)。

Helper の名前の変更

formがFormになったり、javascriptがJsになったりしてる。controllerとかの

$helpers = array('form', 'javascript');

なコードを

$helpers = array('Form', 'Js');

にする

FormHelper から text がなくなった

なぜかなくなった。代わりに input を使う。ただし、input はデフォルトでエラーが起きたときに input 要素の横に div でエラーメッセージを表示するのでそれを表示したくない場合は、error=falseなオプションを渡す必要がある。

Model の invalidFields が何回も呼べなくなったのと、エラーオブジェクトの形式が変わった

validate呼んでエラーがあったら、invalidFields を呼んでエラーオブジェクトを取得してエラー表示とかしてたんだけど、invalidFields を呼ぶと同じエラーが複数個返ってくるようになったので、直接 ModelのvalidationErrorsフィールドを参照してエラーを取得するようにした。

ただし、今までは、validationErrorsはエラーメッセージが直接配列として持っていたのだが、形式が変わって、

array(
  'date' => '正しい日付を入れてちょ'
  'hogeField' => 'hogeFiledにふさわしくない値'
)

という形式になったので注意

helper の継承が変わった???

なんかよくわかってないんだけど、デフォルトの FormHelper とか見ても、

App::uses('AppHelper', 'View/Helper');
class FormHelper extends AppHelper {

な感じになってるので自作の Helper も同様にした。

smarty.php魔改造

CakePHPSmarty をつなぐのに、皆様、ここの Snipetsmarty.php とかにして使ってると思います。

これも改造が必要です。

まず、VIEWSとかの定数を使ってる部分があるのですが、前述のとおり、VIEWSのdefineは無くなったので、App.'View' とかに適宜書き換えましょう。

また、SmartyViewの親クラスであるViewクラスの処理も書き換わったので、書き換える必要がある。
_renderメソッドを以下のようにして

	function _render($___viewFn, $___dataForView = array())
	{

	    if (!$this->_helpersLoaded) {
	        $this->loadHelpers();
	    }

		$this->register_functions();

		foreach($___dataForView as $data => $value)
		{
			if(!is_object($data))
			{
				$this->Smarty->assign($data, $value);
			}
		}

		foreach($this->viewVars as $data => $value) {
		    if(!is_object($data))
		    {
		        $this->Smarty->assign($data, $value);
		    }
		}
		$this->Smarty->assign_By_Ref('view', $this);
	    ob_start();
		echo $this->Smarty->fetch($___viewFn);
		return ob_get_clean();
	}

register_functionsメソッドを以下のようにした

	function register_functions() {
	    	$helpers = HelperCollection::normalizeObjectArray($this->helpers);
		foreach ($helpers as $name => $properties) {
			list($plugin, $class) = pluginSplit($properties['class']);
			if (method_exists($this->{$class}, '_register_smarty_functions')) {
			$this->{$class}->_register_smarty_functions($this->Smarty);
			}
		}
	}