Magento1.x エクステンション入門


このエントリはM[agento Advent Calendar](http://www.adventar.org/calendars/931)の7日目です。

## 概要
Magento 1.xでエクステンションの開発を始めるのに必要なファイルのリストと、それぞれの役割について説明します。

＊世間ではMagento2.0が話題になっていますが、そこは空気を読みません。。。

今回は **Magentoにエクステンションとして認識されるところまで** をゴールとしています。
そのため今回の内容だけで、具体的になにか便利な機能を持ったエクステンションが完成するわけではありません。

実際のプラグインの作成例については、おいおい、お見せしていければと考えております。

## 想定している読者
 * Magentoのカスタマイズを始めようと思っている方。
 * PHPによるプログラミング経験はあるが、Magentoは初めての方。

## エクステンションの役割
まず前提の確認です。
エクステンションは、どのような場面で必要になるのでしょうか。

実際には、大きく分けて以下の2つの場合があると考えています。

 * 標準で用意されていない機能を実装したい場合。
 * 標準で用意されているものについて、その動作を変更したい場合。

標準の動作を上書きするには、他に **コードプール** という仕組みを利用する方法もあるのですが、パッチ適用を始めとしたメンテナンスのことを考慮すると、エクステンション化していくことが最善です。

### 寄り道：コードプールについて
エクステンションの説明に入る前に、「コードプール」について説明をしておきます。

コードプールは、簡単に言うと **読み込まれるソースコードの参照順序に関する仕組み**のことです。

具体的にはMagentoのインストールフォルダ以下、「app/code」ディレクトリに

 * core
 * community
 * local

という3つのフォルダがあるのですが、この中に **同じパスのファイル名が存在する場合、local → community → coreの順番で参照されます。**

言い換えると、「core」フォルダに中にあるMagentoの配布物ファイルを「local」にコピーすることで、Magentoオリジナルのファイルを残しつつ、その内容を改変することができるようになる、ということです。

例えば、Magentoのインストールディレクトリに

 * app/code/core/Mage/Catalog/Block/Product.php
 * app/code/local/Mage/Catalog/Block/Product.php

という2つのファイルが存在すると、app/code/coreに入っているファイルは無視され、app/code/localに入っているファイルのみが利用されることとなります。

しかしながら、ファイルをコピーしていることに変わりはありませんので、パッチ適用を行った後などで、プログラムが正常に動作しなくなる可能性はありますので、注意は必要です。

それぞれのフォルダの意味としては

 * core → Magentoのリリース物。
 * community → サードパーティが配布しているエクステンション。
 * local → そのサイト固有のコード。

という形になります。

## エクステンションに含まれるファイル
エクステンションを作成するのに必須となるファイルについて説明します。

コードプールの概念はエクステンションにも適用されますので、ファイルを配置するフォルダは「community」もしくは「local」から選ぶことができますが、ここでは「community」としています。

以下の表はMagentoのインストールディレクトリの構成を表しており、数字の大きい方がネストが深いことを示しています。

なお、Magentoエクステンションには役割の決まった多くのフォルダが定義されていますが、今回の目的は「Magentoにエクステンションとして認識させる」ことですので、そのために必要なファイルだけを記載しています。

便利な機能を持ったプラグインを開発するには、この他にも多くのリソースが必要となるのですが、それはまたおいおい説明してくこととします。

| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|:--|:--:|:--:|:--:|:--:|:--:|:--:|
| app | code | community | [NameSpace] | [ExtensionName]| 　|　 | 
| 　 |　 |　 |　 |　 | etc |　 | 
| 　 |　 |　 |　 |　 | 　| **config.xml** | 
| 　 |　 |　 |　 |　 | Helper |　 |
| 　 |　 |　 |　 |　 |　 | **Data.php** |
| 　 | etc | modules |　 |　 | 　 |　 | 
| 　 |　 |　 | **[namespace]_[extensionName].xml** |　 | 　 |　 | 

## 作成手順
1. 「NameSpace」(主にベンダー名)と「ExtensionName」(作成するエクステンションの名前)を決めます。
2. 前述の通りにファイルを作成し、Magentoのインストールディレクトリにアップロードします。
3. Magentoの管理画面を開き、インストール済エクステンション一覧に、新しく作成したエクステンションが追加されていることを確認します。

今回は

 * 「NameSpace」→「 **Advent2015** 」
 * 「ExtensionName」→「 **Firstext** 」

とします。

それでは進めていきましょう。

## ファイルの作成
## app/code/community/Advent2015/Firstext/etc/config.xml
config.xmlは以下のような内容となります。
構造として特徴的なのは、「NameSpace_ExtensioName」がノード名となるという部分です。

Magentoはここに書かれた名前を頼りに対応するファイル名やクラス名を検索していきます。

```
<?xml version="1.0"?>
<config>
    <modules>
        <Advent2015_Fristext>
            <version>0.0.1</version>
        </Advent2015_Fristext>
    </modules>
    <global>
        <helpers>
            <advent2015_fristext>
                <class>Advent2015_Firstext_Helper</class>
            </advent2015_fristext>
        </helpers>
    </global>
</config>
```

## app/code/community/Advent2015/Firstext/Helper/Data.php
ヘルパークラスです。

今回は特に役割がありませんが、「ロケールに応じたメッセージをcsvから読み込んで出力する」という機能を担っている関係で、暗示的に使われることもあります。

そのため、特に用がなくても作成しておいた方が無難です。

```
<?php
class Advent2015_Firstext_Helper_Data  extends Mage_Core_Helper_Abstract {
}
```

## app/etc/modules/Advent2015_Firstext.xml
エクステンションの定義ファイルです。
この部分はどのプラグインでもほぼ固定の内容なのですが、無いとエクステンションとして認識されないため、注意が必要です。

```
<?xml version="1.0"?>
<config>
    <modules>
        <Advent2015_Fristext>
            <active>true</active>
            <codePool>community</codePool>
        </Advent2015_Fristext>
    </modules>
</config>
```

## アップロード & 動作確認
ここまでのコードをMagentoをインストールしたサーバの「app」ディレクトリに上書きしたら、以下の手順で動作確認をします。

 1. 管理画面を開く。
 2. 「システム」→「設定」を開く。
![sc_2015-12-07_17_36_43.png](https://qiita-image-store.s3.amazonaws.com/0/50449/c6afd91b-cc07-221b-7472-cf49704287b4.png "sc_2015-12-07_17_36_43.png")

 3. 「高度な設定」 → 「無効なモジュール出力」を開く。
![sc_2015-12-07_17_37_04.png](https://qiita-image-store.s3.amazonaws.com/0/50449/5464d2df-ff02-c082-5fb3-1f1a9df55f0a.png "sc_2015-12-07_17_37_04.png")

これで、図のように「Advent2015_Fristext」という行が表示されていれば成功です。

＊Magentoの新規エクステンションは(キャッシュの設定にもよりますが)、ファイルをコピーした後、次のhttpアクセスが発生した際に読み込まれます。

＊基本的に、開発時にはキャッシュを無効にしておくことをおすすめします。
　管理画面で「システム」→「キャッシュ管理」を開き、表示されているテーブルの左端にある「全て選択」をクリック → テーブル右にあるコンボボックスで「無効」を選択して、「更新」ボタンをクリックします。

## まとめ
ここまで、「自分の書いたコードをMagentoにエクステンションとして認識させる方法」について解説しました。

次回以降、より具体的なプラグイン開発の方法について踏み込んで行ければと思っています。

明日は[HirokazuNishさんのMagentoでアクセス集中を乗り切るには〜後編〜](http://www.adventar.org/calendars/931#list-2015-12-08)となります。
どうぞよろしくお願い致します。

## 参考
ここまでのコードは、[GitHub](https://github.com/iskou9821/MagentoAdventCalendar2015/tree/master/20151207/app)にもアップしています。
そちらも参考にして下さい。