Cosa faccio quando un'estensione sovrascrive una classe a livello mondiale e voglio usare l'originale?

magento.stackexchange https://magento.stackexchange.com/questions/9

  •  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?

È stato utile?

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:

  1. Crea una nuova estensione del proprio.
  2. Riscrivere il catalog/product_list_toolbar nell'estensione
  3. Avere il blocco di estendere Mage_Catalog_Block_Product_List_Toolbar al posto della classe Amasty.
  4. 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.
  5. 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top