Magento Community Edition 1.9とEnterprise Edition1.14がリリースされてそろそろ4ヶ月が経ちます。
そろそろ過去のバージョンを使っているサイトのアップデートを検討される時期に来ているのではないかと思うのですが、カスタマイズの内容によってはCommunity Edition1.9 / Enterprise Edition 1.14にアップデートする際にトラブルが発生することがあります。

このエントリでは、トラブルが発生しそうなポイントについて解説した上で、対策とアップデート手順について説明します。

最新バージョンで加えられた変更点

最新バージョンのMagentoでは、

  • レスポンシブデザインテーマの採用
  • theme.xmlの採用によるフォールバック機構の改良
  • チェックアウト処理の見直しによるパフォーマンスアップ
  • 税計算処理の見直し

といった変更が行われています。
アップデートに伴う画面上の新機能というのは特段ないのですが、プログラムの面では熟成が進められている、というイメージです。

フォールバック機構の変更に伴うエクステンションとの競合

さて、最新バージョンで後方互換性を維持しながらも新しい試みを導入しているのが、フォールバック機構です。
フォールバック機構については別エントリで解説しているので、そちらをお読みください。

このフォールバック機構ですが、導入しているエクステンションのバージョンが古い場合に競合が発生します。
その理由は、「Mage_Core_Model_Design_Packageクラスに__constructメソッドが新たに定義された」 ことに起因します。

CE 1.8 / EE 1.13まではこのクラスに__constructメソッドは定義されていなかったため、このクラスをrewriteするエクステンションはバージョンアップしても問題はありませんでした。
ところが、最新版では__constructメソッドが定義されるようになったため、適切に処理が記述されていない場合はエラーになります。

対処方法

この問題に対処するためには、rewriteを行っている該当のエクステンション側クラスを探し、__constructメソッドに以下の内容をメソッドの適切な位置に追加します(エクステンションによって追加する位置は変わります)。

        if (method_exists(get_parent_class($this), '__construct')) {
            parent::__construct();
        }

税計算処理の変更に伴う端数ズレ問題

MagentoはCE-1.7 / EE-1.12以降のバージョンで、税計算処理が大きく変わっています。1.8 / 1.13でも変更が加えられましたが、1.9 / 1.14でも変更が加えられています。
特に税計算方法を「外税かつ伝票合計」にしている場合は、1.9 / 1.14で誤差が発生します。

例えば1.8 / 1.13では、Mage_Tax_Model_Sales_Total_Quoteの_totalBaseCaclulationメソッドには以下のように書かれています。

foreach ($taxGroups as $rateKey => $data) {
            $rate = (float) $rateKey;
            $inclTax = $data['incl_tax'];

            $totalTax = $this->_calculator->calcTaxAmount(array_sum($data['totals']), $rate, $inclTax, false);
            $totalTax += array_sum($data['weee_tax']);
            $baseTotalTax = $this->_calculator->calcTaxAmount(array_sum($data['base_totals']), $rate, $inclTax, false);
            $baseTotalTax += array_sum($data['base_weee_tax']);
            $this->_addAmount($totalTax);
            $this->_addBaseAmount($baseTotalTax);
            $totalTaxRounded = $this->_calculator->round($totalTax);
            $baseTotalTaxRounded = $this->_calculator->round($totalTaxRounded);
            $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTaxRounded, $baseTotalTaxRounded, $rate);
        }

これが1.9 / 1.14では以下のように書かれています。

foreach ($taxGroups as $taxId => $data) {
            if ($catalogPriceInclTax) {
                $rate = (float)$taxId;
            } else {
                $rate = $data['applied_rates'][0]['percent'];
            }

            $inclTax = $data['incl_tax'];

            $totalTax = array_sum($data['tax']);
            $baseTotalTax = array_sum($data['base_tax']);
            $this->_addAmount($totalTax);
            $this->_addBaseAmount($baseTotalTax);
            $totalTaxRounded = $this->_calculator->round($totalTax);
            $baseTotalTaxRounded = $this->_calculator->round($totalTaxRounded);
            $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTaxRounded, $baseTotalTaxRounded, $rate);
        }

一見すると問題ないように見えるのですが、日本円(もしくは他の小数点以下を使わない通貨)で処理する場合、本体価格の計算だけでなく、税額の計算処理でも小数点以下の切り捨て処理を行うことになります。
1.8 / 1.13までの処理は、課税対象額を合計してから税計算処理をしていました(普通に考えると妥当な処理です)。ところが1.9 / 1.14ではあらかじめ算出した税額を全て合計してから端数処理をしています。この方式だと、税額に付随する小数点以下の数字が積み重なった結果、端数ズレに発展する場合があります。
1.9 / 1.14にアップデートする際には、使用している日本語化エクステンションが、きちんと税計算処理の変更に追従しているかを確認する必要があります。

正しいアップデートの手順とは

このような現象はどのバージョンからのアップデートにおいても発生しえます。
問題を回避してアップデートを行うには、以下の手順にそってアップデート検証作業を進める必要があります。

  1. 導入しているエクステンションの最新版がないかを確認する
  2. 最新バージョンがある場合はそのバージョンを入手する
  3. アップデート前にエクステンションを最新バージョンにしておく
  4. 動作が問題なければMagentoをアップデートする
  5. エクステンション以外でカスタマイズしている箇所の調整を行う

エクステンションの導入数が少なければ少ないほど、この手間は少なくなりますが、たいていのサイトではカスタマイズの度合いに比例した数のエクステンションが導入されていると思います。
(もしくはカスタマイズコードの量も多くなると思います)

アップデートはMagentoをセキュアに保ち、より高いパフォーマンスを手に入れるために欠かせない作業です。
バージョンアップの度にアップデートコストを掛けることは難しいかもしれませんが、2つまたは3つ程度バージョンが最新版と離れたタイミングでアップデートを行うことが望ましいと言えます。