Cosa faccio quando un'estensione sovrascrive una classe a livello mondiale e voglio usare l'originale?
-
16-10-2019 - |
Domanda
Stiamo usando un'estensione che sovrascrive a livello mondiale il blocco Mage_Catalog_Block_Product_List_Toolbar.
<global>
<blocks>
<catalog>
<rewrite>
<product_list_toolbar>Amasty_Shopby_Block_Catalog_Product_List_Toolbar</product_list_toolbar>
</rewrite>
</catalog>
</blocks>
</global>
Mentre l'estensione funziona nel contesto di una categoria di navigazione più livelli, la classe riscritto non funziona correttamente quando inseriamo una lista dei prodotti arbitraria in un altro (personalizzato) vista nel nostro modulo di in-house. Se prendiamo l'estensione di sovrascrittura solo a scopo di test, tutto funziona bene.
Come possiamo annullare riscrittura di una proroga solo per il nostro proprio controller, senza modificare il codice della comunità dello sviluppatore estensione?
Soluzione
Avvertenze: Non c'è modo progettato per fare quello che stai chiedendo nel sistema. Il seguente dovrebbe funzionare, ma non ho mai provato fuori ampiamente su un sistema di produzione, e ci possono essere situazioni in cui causerà più problemi che ne vale la pena. procedere solo se sei a tuo agio problemi di debug relativi alle mutevoli le riscritture di un sistema di lavoro.
Fase 1 è allentato le riscrittura. L'albero di configurazione Magento può essere modificata in fase di esecuzione. Quindi, se si esegue il seguente codice
$config = Mage::getConfig();
$config->setNode(
'global/blocks/catalog/rewrite/product_list_toolbar',
'Mage_Catalog_Block_Product_List_Toolbar'
);
Poi Magento istanzierà blocco Mage_Catalog_Block_Product_List_Toolbar
originale per il resto della richiesta.
Fase 2 è decidere dove chiamare questo nel vostro modulo. Dal momento che questo è solo per il controller ed è la riscrittura di un blocco che non sarà un'istanza fino alla fine del tuo controller, mi piacerebbe aggiungere un metodo per la classe controllore qualcosa di simile
protected function _undoRewrites()
{
$config = Mage::getConfig();
$config->setNode(
'global/blocks/catalog/rewrite/product_list_toolbar',
'Mage_Catalog_Block_Product_List_Toolbar'
);
}
e poi basta chiamare questo metodo all'inizio di ciascuna delle tue azioni
public function indexAction()
{
$this->_undoRewrites();
$test = Mage::getSingleton('core/layout')->createBlock('catalog/product_list_toolbar');
var_dump($test);
}
Questo può sembrare un po 'goffo, ma penso che sia una buona idea di essere goffo (vale a dire ovvio) quando sei stato intelligente con oggetti di sistema di Magento. Un altro posto per questo potrebbe essere gli eventi controller_action_predispatch
o controller_action_predispatch_front_controller_action
e / o applicati in modo condizionale.
Basta ricordare la riscrittura non sarà annullata fino a quando questo metodo viene chiamato. Ciò significa che se si tenta di creare un'istanza di un blocco prima di chiamare _undoRewrites
, la classe riscritto verrà utilizzato per creare un'istanza dell'oggetto.
Altri suggerimenti
Soluzione 1:
Si può cercare di creare un'istanza della classe direttamente (via php) nel controller
anziché
$this->getLayout()->createBlock('catalog/product_list_toolbar');
qualcosa di simile:
$block = New Magento_Catalog_Product_List_Toolbar;
$this->getLayout()->addBlock(....);
Soluzione 2:
Un altro approccio sarebbe creare una nuova classe, nel vostro modulo, che estende la classe originale e l'uso che uno.
Soluzione 3:
In caso contrario, se l'estensione non è criptato (che noi tutti amiamo open source :) Si può cercare di scoprire il motivo per cui si rompe la tua roba
Se esistono più riscritture per lo stesso alias di classe, quindi l'ultimo dei Magento config caricatore analizza da config.xml "vince". Mi piacerebbe attaccare questo problema:
- Crea una nuova estensione del proprio.
- Riscrivere il
catalog/product_list_toolbar
nell'estensione - Avere il blocco di estendere
Mage_Catalog_Block_Product_List_Toolbar
al posto della classe Amasty. - Liberamente commentare la classe spiegando che questo conflitto riscrittura è intenzionale. Se non si desidera un altro sviluppatore che corre MageRun per cercare di "fissare" il conflitto riscrittura che avete appena creato.
- Aggiungi una dipendenza nella app di tua estensione file / etc / modules / blah.xml per garantire la vostra estensione viene caricato dopo quella Amasty.
Simile a quello che Francesco ha suggerito sopra, ma credo che si può effettivamente passare il nome completo della classe per getModel. In questo modo, si sta un po 'ancora facendo la stessa cosa, ma con metodi di base per farlo. Io non sono del tutto sicuro dei vantaggi / svantaggi di questo metodo, ma ho pensato di buttare questo là fuori come idea.
Mage::getModel('Mage_Catalog_Block_Product_List_Toolbar');
Una nota a parte, credo che questo sarà il modo standard per classi di carico in Magento2.
Si ha bisogno di fare un leggero cambiamento nel codice di estensione ho paura. Non riscrivere la classe nel proprio config.xml
più, basta cambiare Amasty_Shopby_Block_Catalog_Product_List_Toolbar
per estendere la vostra classe che a sua volta si estende Mage_Catalog_Block_Product_List_Toolbar
.