Bir uzantı global olarak bir sınıfın üzerine yazdığında ve orijinali kullanmak istediğimde ne yapabilirim?


42

Mage_Catalog_Block_Product_List_Toolbar bloğunun üzerine yazan bir uzantı kullanıyoruz.

<global>
    <blocks>
        <catalog>
            <rewrite>
                <product_list_toolbar>Amasty_Shopby_Block_Catalog_Product_List_Toolbar</product_list_toolbar>
            </rewrite>
        </catalog>
    </blocks>
</global>

Uzantı, katmanlı bir gezinme kategorisi bağlamında çalışırken, yeniden yazılmış sınıf, kendi kurum içi modülümüzde başka bir (özel) görünüme rasgele bir ürün listesi eklediğimizde düzgün çalışmaz. Uzantıyı yalnızca test amacıyla yazmaktan çıkarırsak, her şey yolunda gider.

Uzantı geliştiricisinin topluluk kodunu düzenlemeden bir uzantının yeniden yazılmasını yalnızca kendi denetleyicimiz için nasıl geri alabiliriz?


2
Sınıfa değiştirirseniz muhtemelen asla bu ancak sen kendi uzantısı Your_Extension_Block_Catalog_Product_List_Toolbar bu uzantılar sınıfını yeniden yazmak isteyebilirsiniz çalıştı ... Shopby uzantısı kırmak ancak edeceğiz Amasty_Shopby_Block_Catalog_Product_List_Toolbar uzanır
Sander Mangel

Söyleyebileceğim kadarıyla, Magento <rewrite>sınıf başına yalnızca bir taneye izin veriyor , bu yüzden çekirdek sınıfı genişleten kendi sınıfımı oluşturabilsem de, getBlock('catalog/product_list_toolbar')fabrika yöntemiyle nasıl çalışacağımdan emin değilim .
Aaron Pollock,

Ücretli bir eklenti ise, Amasty desteğine başvurmanız gerekir, bu hata gibi görünüyor
Fra

sorunu tam olarak belirlediniz mi? karşılaştığınız problemin sebebi nedir (genişletilmiş sınıfta hangi fonksiyon)?
FlorinelChis

1
@AaronPollock belki, ama bu problem hala tam da ihtiyaç duyduğu kadar geniş şeyler yazan bir eklentiden kaynaklanıyor olabilir. Belki de kalıtım modelinin kendisini yeniden incelemekle daha iyi oluruz. Belki karışımlar veya özellikler yardımcı olacaktır.
kojiro

Yanıtlar:


25

Uyarılar: Sistemde istediğini yapmanın tasarlanmış bir yolu yok. Aşağıdakiler işe yaramalı, ancak bir üretim sisteminde daha önce hiç denemedim ve buna değmeyecek kadar sıkıntıya neden olabileceği durumlar olabilir. Yalnızca, çalışan bir sistemin yeniden yazımlarının değiştirilmesiyle ilgili sorunlarda hata ayıklama konusunda rahatsanız devam edin.

Adım 1, yeniden yazma işlemini geri alıyor. Magento konfigürasyon ağacı çalışma zamanında değiştirilebilir. Yani, aşağıdaki kodu çalıştırırsanız

$config = Mage::getConfig();        
$config->setNode(
    'global/blocks/catalog/rewrite/product_list_toolbar',
    'Mage_Catalog_Block_Product_List_Toolbar'
);

Sonra Magento Mage_Catalog_Block_Product_List_Toolbar, isteğin geri kalanında orijinal bloğu başlatır .

Adım 2, modülünüzde bunun nereden çağırılacağına karar veriyor. Bu sadece kontrol cihazınız için olduğundan ve kontrol cihazınızın sonuna kadar başlatılmayacak bir bloğu yeniden yazdığından kontrol ünitenize böyle bir yöntem eklerim.

protected function _undoRewrites()
{
    $config = Mage::getConfig();        
    $config->setNode(
        'global/blocks/catalog/rewrite/product_list_toolbar',
        'Mage_Catalog_Block_Product_List_Toolbar'
    );    
}

ve ardından eylemlerinizin başında sadece bu yöntemi arayın.

public function indexAction()
{
    $this->_undoRewrites();
    $test = Mage::getSingleton('core/layout')->createBlock('catalog/product_list_toolbar');        
    var_dump($test);
}

Bu biraz tıknaz görünebilir, ancak Magento'nun sistem nesnelerine zeki olduğunuzda tıknaz olmanın iyi bir fikir olduğunu düşünüyorum. Bunun başka bir yer olabilir controller_action_predispatchveya controller_action_predispatch_front_controller_actionolay ve / veya şartlı uyguladı.

Unutmayın, yeniden yazma yöntemi bu yöntem çağrılıncaya kadar geri alınmaz. Bu, çağırmadan önce bir bloğu başlatmaya çalışırsanız _undoRewrites, yeniden yazılmış sınıf nesneyi başlatmak için kullanılır.


19

1. Çözüm:
Sınıfınızı doğrudan kontrol cihazınızda (php yolu) başlatmayı deneyebilirsiniz

onun yerine

$this->getLayout()->createBlock('catalog/product_list_toolbar');

gibi bir şey:

$block = New Magento_Catalog_Product_List_Toolbar;
$this->getLayout()->addBlock(....);

2. Çözüm:
Başka bir yaklaşım, modülünüzde orijinal sınıfı genişleten ve onu kullanan yeni bir sınıf oluşturmak olacaktır.

Çözüm 3:
Aksi takdirde, uzantı şifrelenmemişse (hepimiz açık kaynağı severiz :) neden bu öğelerin kırıldığını öğrenmeye çalışabilirsiniz.


Çözüm 2 işe yarıyor (pragmatik çözüm), ancak rewriteaynı temel sınıfta bir saniye yapamam diye harika değil . Bu nedenle fabrika yöntemi işe yaramaz (bunu zaten düşündüğümü farkettiniz). Belki bunu yapmanın bir Magento yolu yoktur, ama daha iyi bir yol olup olmadığını görmek için biraz bekleyelim.
Aaron Pollock,

2. çözüm, birlikte gideceğim şeydi ... Francesco'nun cevabını görene kadar bunu önermek için hazırlanıyordum. ;)
davidalger

1
Çözüm 2'yi en iyi sevmeme rağmen, çözüm 1'e bir not: ayrıca $this->getLayout()->createBlock("Mage_Catalog_Block_Product_List_Toolbar"), bir blok sınıfı bağlamındayken , createBlock için tam bir sınıf adı da sağlayabilirsiniz . /Parametrede hiç yoksa, Magento sadece sınıfı aramak için kullanılan dizgiyi kullanır.
Matthias Zeis

1
@Aaron Pollock, aynı temel sınıfta ikinci kez yeniden yazabilirsin. Modül ad alanını Z (A'dan sonra gelen herhangi bir harf) olarak adlandırın ve magento Amasty yerine kullanacaktır.
Amasty

5

Aynı sınıf takma adı için birden fazla yeniden yazma varsa, Magento config yükleyicisi en sonuncusu config.xml dosyasından ayrıştırır. Bu soruna şöyle saldırırdım:

  1. Kendinize ait yeni bir uzantı oluşturun.
  2. catalog/product_list_toolbarUzantınızdakileri tekrar yazın
  3. Mage_Catalog_Block_Product_List_ToolbarBloğunuzun Amasty sınıfı yerine genişletilmesini sağlayın.
  4. Sınıfınıza, bu yeniden yazma çatışmasının kasıtlı olduğunu açıklamak için liberal bir şekilde yorum yapın. MageRun çalıştıran başka bir geliştiricinin az önce oluşturduğunuz yeniden yazma çatışmasını "düzeltmeye" çalışmasını istemiyorsunuz.
  5. Uzantınızın Amasty’den sonra yüklenmesini sağlamak için uzantınızın app / etc / module / blah.xml dosyasına bir bağımlılık ekleyin.

1

Francesco'nun yukarıda belirttiğine benzer, ancak inanıyorum ki tam sınıf adını getModel'e yazabilirsin. Bu şekilde, yine de aynı şeyi yapıyorsunuz, fakat bunu yapmak için çekirdek yöntemleri kullanıyorsunuz. Bu yöntemin artılarını / eksilerini tam olarak bilmiyorum ama bunu bir fikir olarak atabileceğimi düşündüm.

Mage::getModel('Mage_Catalog_Block_Product_List_Toolbar');

Bir yandan, bunun Magento2'deki sınıfları yüklemek için standart yol olduğuna inanıyorum.


1

Korkarım uzatma kodunda küçük bir değişiklik yapmanız gerekiyor. config.xmlArtık sınıfı kendi başınıza yazmayınız, Amasty_Shopby_Block_Catalog_Product_List_Toolbarsırayla sınıfınızı genişletecek şekilde değiştiriniz Mage_Catalog_Block_Product_List_Toolbar.


Çekirdek kod gibi bir uzantı kodu görüyorum - başka birinin işi (temiz bir şekilde yükseltme yeteneğini korumak için). Dokunmaktan kaçınmanın bir yolu olmalı. Ayrıca, Amasty sınıfı, rastgele bir ürün listesi bağlamında temel işlevselliği bozuyor. Kendi işlevselliğimi enjekte etmiyorum; Temel işlevselliği canlandırmam gerekiyor. Çözümümüzü takip edersem, kendi sınıfım boş olurdu ve oraya koyduğum herhangi bir girişimin yerine, daha önceki Amasty sınıfının üzerine yazılırdı.
Aaron Pollock,

Bu kötü bir alışkanlık. Dış modüllere her zaman dokunulmamalıdır. Modülünüzü güncellemeniz gerekirse, tüm değişikliklerinizi yeni sürümde yinelemeniz gerekir. Bu, bakım açısından kabus olabilir.
Michael Türk

Yeni bir blok oluşturup Amasty araç çubuğundan, tersi yönde genişletmek daha iyi olur.
Amasty
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.