ただの技術者ぶろぐ

大阪に住んでる技術者が書く覚書ぶろぐ。

EC-CUBE3で遊ぼう3日目

EC-CUBE3で遊ぼう3日目

プラグインジェネレーター コマンドのバグを直そう。

いきなりハードルを上げた感がありますが、今回は画面がどうとか、機能がどうとかではなくて、純粋なコアコードのバグ修正(機能改善?)です。

前回プラグインジェネレーターを用いて管理画面の機能を追加しましたが、その中に[lower_code]なる記述が残っていたと思います。

NewSample0001ServiceProviderから抜粋
    public function register(BaseApplication $app)
    {
            // プラグイン用設定画面
        $app->match('/'.$app['config']['admin_route'].'/plugin/NewSample0001/config', 'Plugin\NewSample0001\Controller\ConfigController::index')->bind('plugin_NewSample0001_config');

        // 独自コントローラ
        $app->match('/plugin/[lower_code]/hello', 'Plugin\NewSample0001\Controller\NewSample0001Controller::index')->bind('plugin_NewSample0001_hello');

の独自コントローラの部分ですが、[lower_code]となっています。これ本来の処理を考えると「$app->match(‘/plugin/newsample0001/hello’, ‘Plugin\NewSample0001\Controller\NewSample0001Controller::index’)->bind(‘plugin_NewSample0001_hello’);」となるべきだと思いますが、置き換えられていません。それを修正しましょう。

ec-cube3のソースコード全体から[lower_code]を検索した場合、以下のファイルのみがヒットします。 f:id:rock-3:20170216102414j:plain [src/Eccube/Command/PluginCommand/Resource/ServiceProvider.php]内のみですね。

プラグインジェネレータを実行すると、[src/Eccube/Command/PluginCommand/PluginGenerator.php]が動作します。そこで[src/Eccube/Command/PluginCommand/Resource/ServiceProvider.php]を用いて新しいプラグインのServiceProviderを構成しています。ここを改修しましょう。

ここで選択肢として考えるべきなのは

  • ServiceProviderに[lower_code]を変換する処理を追記・修正する。
  • そもそも[lower_code]という表現がここでしか使われてないので、別の内容に書き換える。

のいずれにするかという事です。いずれの案でも動くように対応してみましょう。

ServiceProviderに[lower_code]を変換する処理を追記・修正する。

プラグインジェネレーターコマンドを実行して、新プラグインディレクトリ内に各種ファイルを構成するのは[src/Eccube/Command/PluginCommand/PluginGenerator.php]のcreateFilesAndFoldersメソッドです。

メソッド内で[src/Eccube/Command/PluginCommand/Resource]以下のファイルをそれぞれ読み出し、新プラグイン用に変換したのちに書き出しを行っています。EC-CUBE3.0.13では、260行目前後に以下のような処理がありServiceProviderを作っているので、そこに新しい項目を追加します。

[src/Eccube/Command/PluginCommand/PluginGenerator.phpの260行目付近]
// ここからが既存の処理
// ServiceProvider
$pluginFileBefore = file_get_contents($this->app['config']['root_dir'] . '/src/Eccube/Command/PluginCommand/Resource/ServiceProvider.php');
$from = '/\[code\]/';
$pluginFileAfter = preg_replace($from, $code, $pluginFileBefore);
$from = '/\[author\]/';
$pluginFileAfter = preg_replace($from, $author, $pluginFileAfter);
$from = '/\[year\]/';
$pluginFileAfter = preg_replace($from, $year, $pluginFileAfter);
// ここまでが既存処理

// ここに以下の処理を追加する
$from = '/\[lower_code\]/';
$pluginFileAfter = preg_replace($from, mb_strtolower($code), $pluginFileAfter);

ServiceProviderのファイル内容を読み出したのち、[]で囲まれた文字列があれば置き換える処理に[lower_code]を加えています。

[lower_code]を別の表現に書き換える。

そもそも[lower_code]はServiceProviderでしか使われていない指定文字列です。PluginGenerator.phpのControllerやForm作成処理の中で[code_name]を小文字のプラグイン名に変更している処理が存在しています。ServiceProvider側を変更してみましょう。

[src/Eccube/Command/PluginCommand/PluginGenerator.phpの260行目付近]
// ここからが既存の処理
// ServiceProvider
$pluginFileBefore = file_get_contents($this->app['config']['root_dir'] . '/src/Eccube/Command/PluginCommand/Resource/ServiceProvider.php');
$from = '/\[code\]/';
$pluginFileAfter = preg_replace($from, $code, $pluginFileBefore);
$from = '/\[author\]/';
$pluginFileAfter = preg_replace($from, $author, $pluginFileAfter);
$from = '/\[year\]/';
$pluginFileAfter = preg_replace($from, $year, $pluginFileAfter);
// ここまでが既存処理

// ここに以下の処理を追加する
$from = '/\[code_name\]/';
$pluginFileAfter = preg_replace($from, mb_strtolower($code), $pluginFileAfter);
[src/Eccube/Command/PluginCommand/Resource/ServiceProvider.phpの[lower_code]]
// 独自コントローラ
$app->match('/plugin/[lower_code]/hello', 'Plugin\[code]\Controller\[code]Controller::index')->bind('plugin_[code]_hello');

// ログファイル設定
$app['monolog.logger.[lower_code]'] = $app->share(function ($app) {

    $logger = new $app['monolog.logger.class']('[lower_code]');

    $filename = $app['config']['root_dir'].'/app/log/[lower_code].log';
    $RotateHandler = new RotatingFileHandler($filename, $app['config']['log']['max_files'], Logger::INFO);
    $RotateHandler->setFilenameFormat(
        '[lower_code]_{date}',
        'Y-m-d'
    );

    $logger->pushHandler(
        new FingersCrossedHandler(
            $RotateHandler,
            new ErrorLevelActivationStrategy(Logger::ERROR),
            0,
            true,
            true,
            Logger::INFO
        )
    );

    return $logger;
});

以下のように変更する。

// 独自コントローラ
$app->match('/plugin/[code_name]/hello', 'Plugin\[code]\Controller\[code]Controller::index')->bind('plugin_[code]_hello');

// ログファイル設定
$app['monolog.logger.[code_name]'] = $app->share(function ($app) {

    $logger = new $app['monolog.logger.class']('[code_name]');

    $filename = $app['config']['root_dir'].'/app/log/[code_name].log';
    $RotateHandler = new RotatingFileHandler($filename, $app['config']['log']['max_files'], Logger::INFO);
    $RotateHandler->setFilenameFormat(
        '[lower_code]_{date}',
        'Y-m-d'
    );

    $logger->pushHandler(
        new FingersCrossedHandler(
            $RotateHandler,
            new ErrorLevelActivationStrategy(Logger::ERROR),
            0,
            true,
            true,
            Logger::INFO
        )
    );

    return $logger;
});

これで、いずれの修正を行った場合でも、[lower_code]が変更される形になりました。一応こんな感じで修正できますが、基本的にEC-CUBEのコアコードは触らないほうがいいですし、この問題も次期バージョンでは改修されるみたいです。 github.com 一次対応とプラグインジェネレーターがどう動いているかの確認という感じですね。

今日はここまで。