開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. CMS >
  4. baserCMS >
  5. baserCMSアドオンマイグレーターでテーマをbaserCMS3対応だ→テーマのディレクトリ名が原因で失敗
baserCMSアドオンマイグレーターでテーマをbaserCMS3対応だ→テーマのディレクトリ名が原因で失敗

baserCMSアドオンマイグレーターでテーマをbaserCMS3対応だ→テーマのディレクトリ名が原因で失敗

こんにちは、ナカエです。

一昨日baserCMS 3 betaを試す(Vagrant)の記事でbaserCMS2系のテーマを手動で3系対応させようとしていたんですが、
公式の移行用プラグインがあることを記事執筆後に知ったのでVagrantと仮想マシンで試してみたいと思います。

GitHubのレポジトリはこちらです。
BcAddonMigrator(baserCMS アドオンマイグレーター)
basercms/BcAddonMigrator ・GitHub
bc_addon_migrator_github.png

今回の環境

作業するのが主に仮想マシンなので手順は他OSでもあまり変わらないですが、
フォルダ名などは適宜読み替えてください。
  • Windows 7
  • Vagrantの仮想マシンで作業
  • basercms3テスト用のboxを追加・設定済み (boxファイルは前回記事同様に http://basercms.s3-website-ap-northeast-1.amazonaws.com/vagrant_boxes/CentOS-6.4-x86_64-basercms3-beta-v20131011.box を利用)
  • 作業用フォルダ(=Vagrantfileがあるフォルダ) : basercms3-test/
  • ゲストマシンとホストマシンの共有フォルダはデフォルト設定(ホストのbasercms3-test/ = ゲストの/vagrant)
  • 移行するテーマの名前:nextat

準備

テーマのフォルダを作業フォルダ直下に移動

baserCMS2用のテーマ[nextat]をbasercms3-testの直下に配置します。

Githubからプラグインファイルをダウンロード

作業用フォルダ直下にDownload Zipをクリックして落としたzipファイルを解凍し、BcAddonMigrator-masterをBcAddonMigratorにリネームします。Gitが入っていればcloneしたほうが楽ですね。

※注 2013/11/07追記  現在dev-1がバグが修正されたブランチになっています。

仮想マシン起動

> vagrant up

仮想マシンにログイン

?> vagrant ssh

テーマとプラグインを移動

先ほど作業フォルダに入れたテーマとプラグインが、仮想マシンの/vagrantフォルダ以下に共有されているのでコピーします。所有者はapacheに変えておきます。

$ cd /var/www/html/basercms3
$ cp -r /vagrant/BcAddonMigrator app/Plugin/
$ sudo chown -R apache:apache app/Plugins/BcAddonMigrator
$ cp -r /vagrant/nextat app/webroot/theme/
$ sudo chown -R apache:apache app/webroot/themed/nextat

プラグインの利用方法

管理画面ログイン

(前回記事同様Vagrantfileでホスト:8080 / ゲスト:80のポートフォワーディングを既に設定しています)
http://localhost:8080/basercms/admin/users/loginでbaserCMSのログインページにアクセスして管理画面にログインします。
アカウント情報も同じく、ユーザー名:root パス:vagrantです。

プラグインインストール

プラグイン管理でプラグイン一覧を表示し、BcAddonMigratorをインストールします。
bc_addon_migrator_install.png

マイグレーション

※注 2013/10/31 この記事の執筆時点では、テーマのディレクトリ名がアッパーキャメルケース(名前の先頭が大文字&単語の区切りの先頭も大文字)でない場合はビューとヘルパーの中身の置換が動かないので対策が必要と思われます。
仮想マシンを使わずローカルマシンで試している場合は元のテーマをバックアップしてから試しましょう。


※注 2013/11/07追記 早くも修正していただきました。アンダースコア区切りや先頭が小文字のテーマでも動作します。

BcAddonMigratorの管理画面にはテーマのマイグレーションとプラグインのマイグレーション2つのメニューがあります。
bc_addon_migrator.png

テーマのマイグレーションをクリックします。
bc_addon_migrator2.png


この画面でマイグレーションしたいテーマを選択して実行を押すと
bc_addon_migrator3.png

即座に完了しました。

※注 2013/11/07追記 プラグインが修正されたので現在では正常動作します。手動で作業が必要な事項をこなせばテーマの移行は終了となります。以下は参考程度に。




失敗……?

ところがビューのファイルを覗いてみると$bcBaserなどのbaserCMSデフォルトのヘルパーの参照が書き換えられていない……。
ソースを見てみます。
https://github.com/basercms/BcAddonMigrator/blob/master/Controller/Component/BcAddonMigrator3Component.php

BcAddonMigrator3ComponentのmigrateThemaがテーマの移行処理の実体ですね。
/**
 * テーマのマイグレーションを実行する
 * 
 * @param string $theme テーマ名
 */
        public function migrateTheme($theme) {
                
                $this->migrateThemeStructure($theme);
                $newTheme = Inflector::camelize($theme);
                
                $themePath = WWW_ROOT . 'theme' . DS . $newTheme;                
                $this->migrateHelper($themePath . DS . 'Helper');
                $this->migrateView($themePath);
                
        }
処理の順番は、
  • ディレクトリ構造とファイル名の移行 ※ヘルパーのリネーム含む
  • ヘルパーファイルの移行
  • ビューファイルの以降
となっています。
利用しているメソッドをざっと見た感じでは、migrateViewは個々のファイルのヘルパー参照等の書き換えをちゃんと実装しているように見えます。
/**
 * ビューファイルのマイグレーションを実行
 * 
 * @param string $path ビューディレクトリのパス
 * @param string $plugin 古いプラグイン名
 * @param string $newPlugin 新しいプラグイン名
 */
        public function migrateView($path, $plugin = null, $newPlugin = null) {
                
                $Folder = new Folder($path);
                $files = $Folder->read(true, true, true);
                if(!empty($files[1])) {
                        foreach($files[1] as $file) {
                                $File = new File($file);
                                $data = $File->read();
                                $data = preg_replace('/\$bcBaser->/', '$this->BcBaser->', $data);
                                $data = preg_replace('/\$bcTime->/', '$this->BcTime->', $data);
                                $data = preg_replace('/\$bcText->/', '$this->BcText->', $data);
                                $data = preg_replace('/\$bcUpload->/', '$this->BcUpload->', $data);
                                $data = preg_replace('/\$bcXml->/', '$this->BcXml->', $data);

//(以下略)

ビューとプラグインが更新されない原因

あやしいのはmigrateThemeの中のこの箇所ですね。
$newTheme = Inflector::camelize($theme);
$themePath = WWW_ROOT . 'theme' . DS . $newTheme;    
おそらくアンダースコア区切りのスネークケースで記述されている(かもしれない)テーマの名前をCakePHPの流儀に合わせてキャメルケースに変更するためかな?と思うのですが、 以降の処理で参照するディレクトリパスに含まれるテーマ名もアッパーキャメルケースになります。

結果、存在しないディレクトリのパスが以降のmigrateHelperおよびmigrateViewに引数として渡されます。
× /var/www/html/basercms3/app/webroot/themed/Nextat

本当はこのディレクトリ内のファイルを置換して欲しいわけです。
◯ /var/www/html/basercms3/app/webroot/themed/nextat

対策

ソースを弄って対応するなら、
  • テーマのディレクトリ本体もアッパーキャメルケースに合わせてリネームする処理を追加 (おそらくこちらが望ましい動作?)
  • ひとまずテーマのディレクトリ名変更はなかったことにしておいて元のテーマのパスを後続のメソッドの引数に突っ込むように変更
のどちらかでしょう。
※注 2013/11/07追記  後者が正解だったようです。baserCMSのテーマ名はアセットの参照の都合でアンダースコア区切りが基本とのこと。従って下記対応はあまりよろしくないですね。

今回はBcAddonMigratorのソースコードはいじらず暫定的な対応をしておきます。
手っ取り早いのは移行前に手動でテーマのディレクトリ名を アッパーキャメルケースに合わせることです。

という訳でnextatをNextatにリネームして
> vagrant ssh

$ cd /var/www/html/basercms3/app/webroot/theme
$ mv nextat Nextat
この状態でもう一回試すとビューファイルの中まで置換できました。めでたしめでたし。

プラグインの説明によると、追加で手作業が必要な事項は下記の通りだそうなので、うちの場合はあとは独自ヘルパーの参照を書き換えればよさそうですね。
手動で作業が必要な事項

・PaginatorHelperを利用している場合、第1引数と第2引数を入れ替えてください。
・管理画面のアセットファイルは全て admin フォルダに移動になりましたので参照している場合はURLを書き換えてください。
・ヘルパの参照方法が変わりました。独自ヘルパを利用されている場合は、次のように書き換えてください。($uploader → $this->Uploader)
・BcAuthComponent::user() で取得できる配列の階層が変更となりました。モデル名のキーはなくなっています。($data['User']['name'] → $data['name'])

おまけ:ヘルパーのリネーム処理について

検証するためにマイグレーションを何回も実行していたら
独自ヘルパーのファイルがBcTwittercardsHelperHelperHelper・・・Helper.phpというとんでもなく長い名前になっていました。
ヘルパーが*Helper.phpという名前になっていたらリネームしないように、ファイル名チェックの行程があったほうがよさそうですね。
まあそもそも何回もポチポチとマイグレーションの実行ボタンを押したのが悪いんですが。
TOPに戻る