第4回magento cafe plus〜rewriteと独自テーブル
DESCRIPTION
第4回Magento Cafe Plusで使用した資料です。 Rewriteと独自テーブルを使う方法について説明しています。TRANSCRIPT
Magento-JP User Group 西 宏和
モジュール開発入門2
Agenda
• Rewriteの仕組み
• 独自テーブルを使うエクステンション
Rewriteの仕組み
普通にPHPでクラスを呼び出すときは・・・
$foo = new Foo(引数何か);
Magentoのクラス呼び出し
$block = Mage::getBlock(‘catalog/product_view’);
$model = Mage::getModel(‘catalog/product’);
$helper = Mage::helper(‘catalog/output’);
Magentoのクラス呼び出し
• newを使ってインスタンス作成することはあまりない
• Mageクラスのメソッドまたはそれをラップしたメソッドを使うのが一般的
• 完全なクラス名を指定することはしない
• 常にクラスの別名を使用する
• そもそもPHP5.2時代の設計なので名前空間の概念がない
Rewriteとは?
• Magento上のクラス呼び出しを置き換える仕組み
• クラスAのインスタンスを呼び出す際に、実際はクラスBのものが返る
Rewriteを使うメリット
• 呼び出し側のクラスを変更する必要がない
• RewriteしたクラスはRewrite元クラスを継承することで実装量を減らすことができる
Rewriteの制限とデメリット
• Rewriteは1クラス1回しかできない
• Rewriteの定義は後から定義したものが有効になる
• 同じクラスをRewriteしようとしてエクステンション同士が衝突するのは日常茶飯事
• AbstractクラスはRewriteできない
• なぜなら呼び出しメソッドで使用しないから
Rewriteの基本的な仕組み
1.呼び出しメソッドのコール
2.設定データからRewrite定義判定
3.Rewrite定義がある場合は定義されているクラスのインスタンスを作成
4.ない場合は標準の定義クラスのインスタンスを作成
Model/Block/HelperのRewrite<config> <global> <blocks> <catalog> <rewrite> <product_view> Mymodule_Sample_Block_Catalog_Product_View </product_view> </rewrite> </catalog> </blocks> </global> </config>
ControllerのRewrite(その1)
<config> <global> <rewrite> <Mymodule_Example_ExampleController> <from><![CDATA[#/\w+/sales_order/print/#]]></from> <to>/example/example/print/</to> </Mymodule_Example_ExampleController> </rewrite> </global> </config>
ControllerのRewrite(その2)<config> <frontend> <routers> <example> <use>standard</use> <args> <module>Mymodule_Example</module> <frontName>example</frontName> </args> </example> <contacts> <args> <modules> <Mymodule_Example before="Mage_Contacts">Mymodule_Example</Mymodule_Example> </modules> </args> </contacts> </routers> </frontend> </config>
Rewriteでバージョン違いを考慮する必要
• 基本、Rewriteは1クラスにつき1回
• クラス・メソッドによってはバージョンで実装が全く異なる物がある
• 引数が違うものはバージョンが違うと致命的
• つまり、Magentoのバージョン違いを考慮しないと危険なことがある
バージョン別Rewriteをするには
• Observerでバージョンを判定して振り分ける
• Mage::getConfig()->setNode(‘global/models/catalog/rewrite/product_view’, ‘Myextension_Sample_Model_Catalog_Product_View’);のように書く
独自テーブルを使うエクステンション
独自テーブルを使うために必要なこと
• ResourceModelの作成
• config.xmlの定義追加
• セットアップSQLスクリプトの記述
ResourceModelの作成
• Modelディレクトリ下にResourceディレクトリを作る
• Mage_Core_Model_Resource_Db_Abstractを継承したクラスを定義する
• _constructメソッドにマッピングするテーブル名と主キー列を書く
サンプルコード
class Myextension_Sample_Model_Resource_Sample extends Mage_Core_Model_Resource_Db_Abstract { protected function _construct() { $this->_init('sample/sample', 'sample_id'); } !
~以下略~ }
Collectionクラスの作成
• Collectionクラスは結果セットを取得するために使用する
• Collectionクラスを定義したいResourceクラスのファイル名(拡張子除く)でディレクトリを作り、その中にCollection.phpを作る
サンプルコード
class Myextension_Sample_Model_Resource_Sample_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract { protected function _construct() { $this->_init('sample/sample'); } !
~以下略~ !
}
config.xmlへの定義追加<config> <global> <models> <sample> <class>Myextension_Sample_Model</class> <resourceModel>sample_resource</resourceModel> </sample> <sample_resource> <class>Myextension_Sample_Model_Resource</class> <deprecatedNode>sample_mysql4</deprecatedNode> <entities> <sample> <table>myext_sample</table> </sample> </entities> </sample_resource> </models> <resources> <sample_setup> <setup> <module>Myextension_Sample</module> <class>Mage_Eav_Model_Entity_Setup</class> </setup> <connection><use>core_setup</use></connection> </sample_setup> </resources> </global> </config>
セットアップSQLスクリプトの作成
• エクステンションのディレクトリにsql(またはdata)ディレクトリを作る
• 「<エクステンション別名>_setup」というディレクトリをその中に作る
• install-x.x.x.phpは最初に実行されるスクリプト
• upgrade-x.x.x-y.y.y.phpはエクステンションのアップデート時に実行される
• x.x.xやy.y.yはエクステンションのバージョン番号と連動する
サンプルスクリプト$installer = $this; $installer->startSetup(); !
$installer->run( "CREATE TABLE `{$this->getTable(‘sample/sample')}` ( `sample_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `store_id` int(10) unsigned NOT NULL, `comment` text, `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `status` int(10) unsigned NOT NULL PRIMARY KEY (`sample_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; "); !
$installer->endSetup();
またはOOP的に・・・$installer = $this; $installer->startSetup(); !$table = $installer->getConnection() ->newTable($installer->getTable('sample/sample')) ->addColumn('sample_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( 'identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true, ), 'Sample ID') ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array( 'unsigned' => true, 'nullable' => false, 'default' => '0', ), 'Store ID') ->addColumn('comment', Varien_Db_Ddl_Table::TYPE_TEXT, 65536, array( 'nullable' => false, 'default' = “”, ), ’Comment’) ->addColumn('created_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array( ), 'Creation Time') ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array( ), 'Update Time') ->addIndex($installer->getIdxName('sample/sample', array(‘sample_id'))) ->setComment('Sample Table'); $installer->getConnection()->createTable($table); !$installer->endSetup();
画面の作成
• 管理画面を作る際は、GirdとFormを理解することが必要
• Magentoの管理画面フォームなどは比較的テンプレートレスで書ける
• 場合によってはレイアウトXMLも不要
• フロントエンドの場合はマークアップも含めて開発者が実装(これが割とめんどくさい)
実演
おわり