¿Cómo anulo / reescribo una clase de bloque en Magento 1?

12

Nota: Esta es una pregunta canónica que explica completamente cómo funcionan las reescrituras de bloques y puede usarse como destino duplicado para preguntas más específicas de "Cómo anulo el bloque X" o "¿Por qué mi reescritura no funciona?".

Ver también: Buscando preguntas canónicas sobre las anulaciones de Magento 1

Digamos que tengo que hacer cambios en una clase de bloque central en un módulo personalizado (cambiar métodos o agregar métodos). ¿Cómo hago esto, paso a paso?

Fabian Schmengler
fuente

Respuestas:

23

Cada bloque o grupo de bloques se declara en el config.xmlarchivo de un módulo como este (dentro de la <global>etiqueta).
Aquí hay un ejemplo del módulo de catálogo.

    <blocks><!-- marks definition of a block group -->
        <catalog><!-- unique alias for blocks in the module -->
            <class>Mage_Catalog_Block</class><!-- class prefix for all blocks -->
        </catalog>
    </blocks>

Esto significa que se puede crear una instancia de un bloque utilizando el alias catalog/class_name_heredonde class_name_hereestá el resto de la ruta de clase comenzando desde el prefijo.
Esto significa catalog/class_name_hereque se asignará de forma predeterminada a Mage_Catalog_Block_Class_Name_Here.

Para volver a escribir un bloque, necesita crear un módulo que dependa del módulo que está intentando cambiar ( Magento_Catalog) en mi ejemplo.
Y necesita agregar esto en config.xmlla <global>etiqueta debajo .

<blocks>
    <catalog><!-- alias of the block group you are rewriting -->
        <rewrite><!-- reserved tag: specify that you are rewriting something -->
             <class_name_here>YourNamespace_YourModule_Block_Your_New_Class_Here</class_name_here> <!-- tag: the rest of the alias of the class you are rewriting. value: the name of your class that rewrites the core class -->
        </rewrite>
    </catalog>
</blocks>

Luego cree la clase YourNamespace_YourModule_Block_Your_New_Class_Here(siguiendo la estructura de carpetas ZF) y haga que esta clase extienda la clase original.

class YourNamespace_YourModule_Block_Your_New_Class_Here extends Mage_Catalog_Block_Class_Name_Here
{
    //your awesome code here
}

Cuando haya terminado, desactive la compilación y actívela nuevamente (si es necesario) y borre la memoria caché.

Esto no funcionará para bloques abstractos.
Solo funciona para clases que se instancian.

Ejemplo

Supongamos que desea reescribir el archivo app \ code \ core \ Mage \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php que tiene la clase Mage_Catalog_Block_Product_View_Options_Type_Selecten su propio módulo Marius_Test .

Entonces necesitaría esta entrada en su config.xml:

<blocks>
    <catalog>
        <rewrite>
            <product_view_options_type_select>Marius_Test_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>
        </rewrite>
    </catalog>
</blocks>

app \ code \ local \ Marius \ Test \ Block \ Catalog \ Product \ View \ Options \ Type \ Select.php :

class Marius_Test_Block_Catalog_Product_View_Options_Type_Select extends Mage_Catalog_Block_Product_View_Options_Type_Select
{
    //your awesome code here
}
Marius
fuente
No funciona. Intento sobrescribir la clase Mage_Catalog_Block_Product_View_Options_Type_Selecten app \ code \ local \ WR \ EPO \ Block \ Catalog \ Block \ Product \ View \ Options \ Type \ Select.php . Lo intenté así: codepen.io/anon/pen/WYOqBr
Negro
Y si no funciona, crees que mi respuesta es incorrecta, así que lo rechazas en lugar de pensar que tal vez estás haciendo algo mal. De todos modos ... reemplace esto <Mage_Catalog_Block_Product_View_Options_Type_Select> WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select </Mage_Catalog_Block_Product_View_Options_Type_Select>con <product_view_options_type_select>WR_EPO_Block_Catalog_Block_Product_View_Options_Type_Select</product_view_options_type_select>y asegúrese de que no haya espacios adentroproduct_view_options_type_select
Marius
Voté en contra porque su respuesta no fue precisa y aunque la seguí paso a paso no produjo el resultado correcto. Usted escribió que tenemos que usar el nombre de la clase, así que lo usé y no funcionó. Tenemos que usar en product_view_options_type_selectlugar del nombre real de la clase Mage_Catalog_Block_Product_View_Options_Type_Select. Si cambias tu respuesta en consecuencia, votaré.
Negro
Si lo lees paso a paso, te perdiste un paso. En el que explico cuál es el alias de clase. Si solo copia, pega y reemplaza, lo hará funcionar. 17 personas entendieron. Creo que lo expliqué bien
Marius
Sí, pero un buen ejemplo es que falta por lo que podemos asegurar que nos la comprensión de su teoría correcta
Negro
4

Para My Point of view, anular y reescribir estas dos cosas son diferentes,

Anular:

Cuando usamos el mecanismo de reserva de diseño, entonces estamos haciendo anulación

Volver a escribir:

Cuando reescribimos las clases principales de magento en nuestra clase, entonces estamos reescribiendo.

1) Ejemplo de anulación:

Si necesito anular el app/code/core/Mage/Catalog/Block/Product/List.phparchivo, copie en mi módulo local con la misma ruta que se muestra a continuaciónapp/code/local/Mage/Catalog/Block/Product/List.php

Esto no es sugerido por magento, pero puede hacerlo de esa manera.

2) Ejemplo de reescritura:

Si quiero reescribir esta clase de bloque, Mage_Adminhtml_Block_Sales_Order_Createcodifico en mi módulo config.xml como a continuación

    <global>
        <blocks>
            <adminhtml>
                <rewrite>

                    <sales_order_create>Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create</sales_order_create>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>

Y en mi clase Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create

Codifico como abajo

class Trimantra_Smallchanges_Block_Adminhtml_Sales_Order_Create extends Mage_Adminhtml_Block_Sales_Order_Create {
      My Function Or funcions That I want to Rewrite..
}
Murtuza Zabuawala
fuente
2

Es importante agregar aquí que las reescrituras en bloque (así como todas las otras reescrituras de módulos Magento) implican un mayor esfuerzo de mantenimiento y, por lo tanto, deben considerarse como una última oportunidad para extender la funcionalidad después de la manipulación de la configuración, los eventos y la personalización del tema.

Posible problema 1: la plantilla reescrita no se actualizará cuando usted u otro responsable actualice los archivos fuente de Magento. Significa que la corrección o mejora de seguridad no se aplicará a su código. Lo mismo se aplica a otras clases reescritas, incluidos los bloques, pero depende de la cantidad de reescritura que se haya realizado (ver más abajo).

Posible problema 2: el bloque reescrito (u otra clase) puede parecer reescrito por otra extensión que usted u otro responsable de mantenimiento intentará instalar. Entonces tendrás que resolver este conflicto.

Alternativa 1: Use eventos, es decir, busque el código que está a punto de reescribir y verifique si hay eventos que podrían usarse para lograr la funcionalidad deseada.

Alternativa 2: Reescribir de manera inteligente, es decir, mirar alrededor: tal vez verifique el lugar donde se instancia la clase que va a reescribir y ver si puede afectar qué clase se elige a través de la configuración o los eventos; tal vez hay una clase alrededor que le permite anular un método de 3 líneas para reemplazar el nombre de clase en lugar de copiar el método de 30 líneas de la clase original a la reescrita.

Anton Boritskiy
fuente