¿Qué hago cuando una extensión sobrescribe una clase a nivel mundial y quiero usar el original?

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

  •  16-10-2019
  •  | 
  •  

Pregunta

Estamos utilizando una extensión que a nivel mundial sobrescribe el bloque 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>

Mientras que las obras de ampliación en el contexto de una categoría de navegación por capas, la clase reescrito no funciona correctamente cuando insertamos una lista de productos arbitraria en otro punto de vista (personalizada) en nuestro propio módulo en el local. Si tomamos la extensión de sobreescritura sólo para propósitos de prueba, todo funciona bien.

¿Cómo podemos deshacer reescritura de una extensión sólo para nuestro propio controlador, sin necesidad de editar un código comunitario de los desarrolladores de extensión?

¿Fue útil?

Solución

Advertencias: No hay ninguna manera diseñada para hacer lo que está pidiendo en el sistema. El siguiente debería funcionar, pero nunca he probado a cabo en gran medida en un sistema de producción, y puede haber situaciones en las que va a causar más problemas que vale la pena. Sólo procederá si estás problemas de depuración confortables relacionados con el cambio de las reescrituras de un sistema de trabajo.

Paso 1 es deshacer la reescritura. El árbol de configuración Magento se puede cambiar en tiempo de ejecución. Por lo tanto, si ejecuta el siguiente código

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

A continuación, Magento creará una instancia del bloque Mage_Catalog_Block_Product_List_Toolbar original para el resto de la solicitud.

Paso 2 es decidir dónde llamar esto en su módulo. Puesto que esto es sólo para su controlador y es la reescritura de un bloque que no se crea una instancia hasta el final de su controlador, me gustaría añadir un método a su clase controlador algo como esto

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

y luego simplemente llamar a este método en el inicio de cada una de sus acciones

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

Esto puede parecer un poco torpe, pero creo que es una idea buena para ser torpe (es decir, obvio) cuando estás siendo inteligente con los objetos del sistema de Magento. Otro lugar de esto podría ser los eventos controller_action_predispatch o controller_action_predispatch_front_controller_action y / o aplicada de forma condicional.

Sólo recuerde la reescritura no se puede deshacer hasta que se llama a este método. Esto significa que si se intenta crear una instancia de un bloque antes de llamar _undoRewrites, la clase reescrito se utiliza para crear una instancia del objeto.

Otros consejos

Solución 1:
Usted puede tratar de crear una instancia de la clase directamente (modo PHP) en su controlador

en lugar de

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

algo como:

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

Solución 2:
Otro enfoque sería crear una nueva clase, en su módulo, que se extiende la clase original y el uso que uno.

Solución 3:
De lo contrario, si la extensión no está encriptada (todos de código abierto amor :) se puede tratar de averiguar por qué se rompe sus cosas

If multiple rewrites exist for the same class alias, then the last one the Magento config loader parses from config.xml "wins". I'd attack this problem by:

  1. Create a new extension of your own.
  2. Rewrite the catalog/product_list_toolbar in your extension
  3. Have your block extend Mage_Catalog_Block_Product_List_Toolbar instead of the Amasty class.
  4. Liberally comment your class explaining that this rewrite conflict is intentional. You don't want another developer who runs MageRun to try and "fix" the rewrite conflict you've just created.
  5. Add a dependency in your extension's app/etc/modules/blah.xml file to ensure your extension is loaded after the Amasty one.

Similar to what Francesco suggested above, but I believe you can actually pass the full class name in to getModel. This way, you are somewhat still doing the same thing, but using core methods to do it. I'm not entirely sure of the pros/cons to this method, but thought I would throw this out there as an idea.

Mage::getModel('Mage_Catalog_Block_Product_List_Toolbar');

On a side note, I believe this will be the standard way to load classes in Magento2.

You do need to do a slight change in the extension code I am afraid. Do not rewrite the class in your own config.xml anymore , just change Amasty_Shopby_Block_Catalog_Product_List_Toolbar to extend your class that in turn extends Mage_Catalog_Block_Product_List_Toolbar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top