2011-01-14 9 views
1

基本的に私たちは複数のウェブサイトを持つ多くのクライアントを持っており、それらのモジュールをたくさん書く必要があります。エクステンションは、Magentoのコアがデフォルトで行う機能をオーバーライドする場合があり、ストアではなく別のストアで行うことがあります。明らかに、私たちはロジックをコードに入れてストアを確認することができますが、これを行うもっとエレガントな方法があると思います。店舗やウェブサイトでモジュールの機能を制限する最良の方法は何ですか

答えて

2

良い質問。

私は別の方法でこの問題を解決しました。 モジュール構造:私の意見については

Custom 
| - Module 
| - - Model 
| - - - Product.php 
| - - - Customer.php 

店から依存するクラスを作成する必要があります。 Store UK用にいくつかの機能を作成する場合は、UKストア用にこのクラスを宣言し、設定ファイルに書き込んで、ファクトリクラスで呼び出す必要があります。 たとえば、設定で。XML

<config> 
     <stores> 
      <store_uk> 
       <catalog_product>Custom_Module_Model_Store_Uk_Product</product_attribute> 
       <customer>Custom_Module_Model_Store_Uk_Customer</customer> 
      </store_uk> 
      <store_en> 
       <catalog_product>Custom_Module_Model_Store_En_Product</catalog_product> 
      </store_en> 
     </stores> 
    </config> 

クラスストアルータを作成します。

class Custom_Module_Model_Store_Router 
{ 
    public function callMethod($method, $args) 
    { 
     if (strpos($method, '/') !== false) { 
      $method = explode('/', $method); 
     } 

     if (count($method) != 2) { 
      return false; 
     } 

     $handler = $method[0]; 
     $method = $method[1]; 

     $object = $this->_getObject($handler); 
     if ($object) { 
      //already checked if method exists 
      retun $object->$method($args); 
     } 

     return false; 
    } 

    public function hasStoreMethod($method) 
    { 
     if (strpos($method, '/') !== false) { 
      $method = explode('/', $method); 
     } 

     if (count($method) != 2) { 
      return false; 
     } 

     $handler = $method[0]; 
     $method = $method[1]; 

     $object = $this->_getObject($handler); 
     if (method_exists($object, $method)) { 
      //Bingo 
      return true; 
     } 

     return false; 
    } 

    protected function _getObject($handler) 
    { 
     $storeCode = Mage::app()->getStore(true)->getCode(); 

     $handlerClassName = Mage::getStoreConfig($storeCode . '/' . $handler); 

     if (empty($handlerClassName)) { 
      return false; 
     } 

     $handlerInstance = Mage::getModel($handlerClassName); 
     //here we can save instance into the _handlers etc. 

     return $handlerInstance; 
    } 
} 

このクラスは、デフォルトのカスタマイズ

//in your custom module product class 
Custom_Module_Model_Product extends Mage_Catalog_Model_Product_Attribute 
{ 
    public function getAttributes($groupId = null, $skipSuper = false) 
    { 
     $routerStore = Mage::getSingleton('custom_module/store_router'); 
     if ($routerStore->hasStoreMethod('catalog_product/getAttributes')) { 
      $attributes = $routerStore->callMethod('catalog_product/getAttributes', array('groupId' => $groupId, 'skipSuper' => $skipSuper)); 
      return $attributes; 
     } 

     return parent::getAttributes($groupId, $skipSuper); 
    } 
} 

そして、このクラスは店で、英国のクラスのみ

//custom module product class for uk store 
Custom_Module_Model_Store_Uk_Product extends Mage_Catalog_Model_Product_Attribute 
{ 
    public function getAttributes($groupId = null, $skipSuper = false) 
    { 
     $attributes = parent::getAttributes($groupId, $skipSuper); 

     // do some specific stuff 

     return $attributes; 
    } 
} 

した後のようになります。あなたはこのステップをクリアするでしょうモジュール構造とカスタマイズクラスは以下の通り:

Custom 
| - Module 
| - - Model 
| - - - Store 
| - - - - Uk 
| - - - - - Product.php 
| - - - - - Customer.php 
| - - - - En 
| - - - - - Product.php 
| - - - - Router.php 
| - - - Product.php 
| - - - Customer.php 

私はこれがあなたのmultistore開発に役立つことを願っています

+0

誰かがこれをやりたければ、これは解決策だと思います。 –

0

これを実現する唯一の方法は、すべてのリライトがカスタマイズのみに依存するため、モジュールのロード方法をロジックをカスタマイズすることだと思います。

最初の考え方は、Mage_Core_Model_Config::_loadDeclaredModules()またはMage_Core_Model_Config::_getDeclaredModuleFiles()をオーバーライドして、ロード設定ファイルの前にストアIDをチェックすることでしたが、このメソッドが呼び出されたときにストアIDが初期化されていないことを認識しました。 Mage_Core_Model_App::run()には、_initCurrentStore()が後で呼び出されることがわかります。

第2のアイデア:ファブリックのカスタマイズ方法Mage::getModel()Mage_Core_Model_Config::getGroupedClassName()を見ると、ノードglobalからのモジュール、ブロック、ヘルパーなどの設定が必要です。このメソッドをオーバーライドして、すべての構成をノード'stores/current_store_code'から取得できるようにすると、すべてのリライトが現在のストアに対してのみロードされます。

しかし、これらのソリューションは実装可能かどうかはわかりません。

+0

ええ、それらはいくつかの良いアイデアは、私は意志彼らと混乱が、非常に少しのことを少し思わあり私たちの状況のた​​めに。私はこの深みをコアに置き換えることを本当に望んでいないでしょう。おそらくモジュールにロジックを入れて、それがどのストアであるかを確認するほうが良いでしょう。 –

4

ここに私が過去に使った共通のイディオムがあります。あなたはクラスをオーバーライドし、一回毎に機能を変更することで、既存のロジックを変更しているとき、それはうまく動作します:

public function overriddenFunc($arg) { 
    if(!$this->checkIfModuleIsEnabledForStore()) { 
     return parent::overriddenFunc($arg); 
    } 

    // do your magic here 
    return $something; 
} 

モジュールが有効になっていない時はいつでもそれは、基本的な機能のオーバーライドのパススルーとして機能します。次に、ストアレベルの構成設定を使用して、ストアごとに機能をオンまたはオフにすることができます。

自分の気持ちを守るためには、必要最小限の機能をオーバーライドしてください。

希望に役立ちます!

おかげで、 ジョー

+0

ジョセフさん、ありがとうございました。 –