Añadir atributos a una categoría eav en Magento

En esta entrada voy a comentar como podremos agregar un nuevo atributo a nuestra categoría. Digo categoría porque es el caso para el que me hizo falta a mí desarrollarlo, pero puedes aplicarlo para cualquier entidad EAV de Magento.

Antes de empezar me gustaría explicar unos cuantos conceptos. Cuando instalamos una extensión, para que esta extensión funcione correctamente puede que sea necesario configurarla de algún modo, como añadir tablas, atributos, etc. Todas estas configuraciones son realizadas desde la carpeta sql y en el interior de esta carpeta podremos encontrar otra llamada nombremodulo_setup. Dentro de esta última tendremos los scripts que se van a ejecutar para modificar cualquier necesidad.

Lo primero que vamos a hacer es configurar el xml para que ejecute el script, esto se hace declarando un recurso. Para ello, en el archivo config.xml que está en la carpeta /etc de nuestro módulo escribimos lo siguiente:

  1. <resources>
  2. <!-- ... -->
  3. <nombremodulo_setup>
  4. <setup>
  5. <module>Magentotutorial_Weblog</module>
  6.  
  7. <class>Magentotutorial_Weblog_Model_Resource_Mysql4_Setup
  8.  
  9. </class>
  10. </setup>
  11. <connection>
  12. <use>core_setup</use>
  13. </connection>
  14. </nombremodulo_setup>
  15. <!-- ... -->
  16. </resources>

Los script del interior de la carpeta sql van a llamarse de la siguiente forma:

mysql4-install-1.0.php   Este será el primer script que se ejecutará.

Posteriormente si realizamos una actualización del módulo tendremos que seguir la siguiente normativa:

mysql4-upgrade-(versión actual)-(versión a la que pasamos).php

un ejemplo:

mysql4-upgrade-1.0-1.1.php

La ejecución de este script lo que hace es crearte una nueva entrada en la tabla core_resource. En esta tabla vamos a tener los módulos que ejecutaron alguna tarea de instalación y almacenaremos la versión en la que estamos actualmente, con lo cual si queremos que se vuelva a ejecutar otra vez el script de instalación debemos de ir a esta tabla y borrar la entrada que se creó para este módulo.

Magento se comporta de la siguiente forma con este script: si en core_resource tenemos la misma versión que la que pone en el script no hace nada, por lo contrario ejecuta el script.

Me paro aquí para comentar el interior del archivo que contiene el script:

  1. <?php
  2.  
  3. echo 'Running This Upgrade: '.get_class($this)."\n <br /> \n";
  4.  
  5. die("Exit for now");
  6.  
  7. ?>

Estas líneas son las primeras que yo pondría en el archivo, para que así, al ejecutar el script se quede parado y muestre el siguiente texto:

 

Running This Upgrade: Magentotutorial_Nombremodulo_Model_Resource_Mysql4_Setup
Exit for now

 

Entonces sabremos que hemos tomado el control de la aplicación y que el proceso de instalación se está ejecutando correctamente.

Vamos a comentar el contenido del resto del archivo:

mysql4-install-1.0.php

  1. <!--?php <br ?--> /*echo 'Running This Upgrade: '.get_class($this)."\n
  2. \n";
  3. die("Exit for now");*/
  4. $installer = $this;
  5. $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
  6. $installer-&gt;startSetup();
  7.  
  8. $setup-&gt;addAttribute('catalog_category', 'inicio', array(
  9. 'group' =&gt; 'General',
  10. 'input' =&gt; 'date',
  11. 'type' =&gt; 'datetime',
  12. 'label' =&gt; 'Inicio campaña',
  13. 'backend' =&gt; 'eav/entity_attribute_backend_datetime',
  14. 'visible' =&gt; 1,
  15. 'required' =&gt; 0,
  16. 'user_defined' =&gt; 1,
  17. 'global' =&gt; Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
  18. ));
  19. $setup-&gt;addAttribute('catalog_category', 'fin', array(
  20. 'group' =&gt; 'General',
  21. 'input' =&gt; 'date',
  22. 'type' =&gt; 'datetime',
  23. 'label' =&gt; 'Fin campaña',
  24. 'backend' =&gt; 'eav/entity_attribute_backend_datetime',
  25. 'visible' =&gt; 1,
  26. 'required' =&gt; 0,
  27. 'user_defined' =&gt; 1,
  28. 'global' =&gt; Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
  29. ));
  30.  
  31. $installer-&gt;endSetup();
  32.  
  33. ?&gt;

 

Explicaremos un poco lo que hace:

Ejecutamos el método addattribute al cual le pasamos la entidad a la que queremos añadir dicho atributo (en este caso ‘catalog_category’), el nombre con el que vamos identificarlo y le pasamos alguno de los parámetros como:

  • Input: es el tipo de entrada del atributo
  • Type: que será el tipo del atributo en la base de datos.
  • Label: es el nombre visual del atributo
  • Backend: el tipo de atributo eav

En el caso de ejemplo hemos insertado un datetime porque necesitábamos tratar con una fecha de inicio y una fecha de fin para la categoría pero podemos añadir los atributos de los diferentes tipos:

Para un textfield:
‘input’ => ‘text’,
‘type’ => ‘text’,

Para un text area:
‘input’ => ‘textarea’,
‘type’ => ‘text’,

Para un tipo fecha:
‘input’ => ‘date’,
‘type’ => ‘datetime’,

Para un tipo select:
‘input’ => ‘select’,
‘type’ => ‘text’,

Según mi experiencia, una vez que encontré la manera de cómo hacer esto la verdad es que me abrió bastante la mente y me hizo ver que el desarrollo de Magento es bastante flexible y que puede que esto lo necesites muy a menudo para carencias que quieras incluir en tu tienda. Espero que os haya resultado interesante y aquí os dejo un enlace donde vi como se hacía esto, que aunque ya está explicado a mí me gusta entenderlo, razonarlo y plasmar mi experiencia personal a la vez que amplío un poco la explicación o me centro en aspectos que no están ya explicados.

Este enlace es bastante completo: Añadir atributos EAV

 

13 comentarios sobre “Añadir atributos a una categoría eav en Magento”

  1. Buenas!

    En primer lugar quería saludar a David, Selo eres un Crack! y en segundo a Rolan (pensaba que lo tuyo era mas eso de las capas, degradados…) jeje

    A lo que vamos… me hace falta crear un atributo nuevo para los productos de Magento. Bueno en realidad lo que necesito es cambiar el tipo de atributo, por ejemplo los productos tienen el atributo color, del tipo select.

    Mi consulta es si se puede cambiar el select, en vez de que salga el desplegable, que hubiera la típica paleta con los colores para que el cliente vea que colores estan disponibles sin tener que pinchar en el desplegable.

    Hasta ahora lo que he conseguido es que al elegir los valores del select me cambiar la imagen creando un producto configurable.

    1. buenas Alex, no se desde donde quieres poner la paleta? supongo que desde el admin, yo lo afrontaría de la siguiente manera, le cambiaría el tipo al atributo color, que eso se puede, mira la tabla eav_attribute en los campos backend_model ,backend_type que ahí creo que es donde viene el tipo de atributo y pondría un tipo cadena y dentro del admin ya me las buscaría para poner la paleta y que al pulsar en el color ponga el valor del color( que finalmente es un valor hexadecimal) en el atributo. Es lo que se me ocurre así de primeras. Alguna otra idea?

      1. lo que necesito cambiar es el frontend, el cliente en vez de pinchar en el select (desplegable) y elegir el color, que directamente se muestren los colores para que el cliente pinche en el color.

        He mirado la tabla eav_attribute y veo que tiene el campo frontend_input, y efectivamente el valor que tiene ahora mismo es ‘select’. No se si tendría que cambiar ese campo y algo del código.

        Creo que desde el backend todo esta correcto porque con la configuración actual podría introducir todos los datos.

          1. Pues de memoria no me lo se, tendrás que buscar el phtml que esta tomando en ese momento, te recomiento que te instales la developed toolbar para saber que plantilla esta cargando en cada momento, suele ser muy útil

  2. Hola,
    Muchas gracias por tu artículo. Me ha ayudado mucho. ¿Cómo accederíamos después al valor del atributo nuevo?
    He añadido un campo con id claim a las categorías. Se guarda perfectamente. Intento coger el valor para mostrarlo en la plantilla pero no lo consigo.
    getStoreCategories() as $_category):
    echo $_category->getData(‘claim’);
    endforeach;
    ?>
    Muchas gracias.

    1. Buenas Ana,

      Gracias a ti por dejar tu opinión.

      Por lo que veo en el código que tienes, estás recorriendo una colección, no se si la colección la estás creando tu o la estas cogiendo mediante algún método de las clases de Magento.
      Si la creas tu: lo mas probable es que tengas un addAttributeToSelect()
      Si la tomas de Magento : Tienes que ver quien está haciendo ese addAttributeToSelect(), para ver el mecanismo que tienen para añadir atributos a la consulta.

      Te pongo un ejemplo: Si quieres mostrar un atributo de producto en el listado de producto. Tendrías que ir al backend de Magento, a la configuración de dicho atributo y marcar la opción de “in product Listing” o algo parecido, que internamente se traduce en que cuando se hace un addAttributeToSelect() va a ir a recopilar dichos atributos.

      Para saber que este es el problema, carga el modelo de una categoría que sepas que tiene dicho atributo y haz el getData del atributo, algo parecido a esto
      $category= Mage::getModel(‘…’);
      echo $category->getData(‘claim’);
      Así te lo debería de estar mostrando.

      Prueba y me cuentas, es un poco lioso de explicar en un texto intuyendo lo que puede pasarte pero espero haberte ayudado.

      1. Hola de nuevo,
        Muchisimas gracias por tu respuesta. Lo he conseguido. Me faltaba cargar el modelo. Voy a dejar aquí el código por si puedo ayudarle a alguien

        Un saludo.

        Este código lo he puesto en catalog/category/list.phtml

        foreach ($this->getStoreCategories() as $_category):
        $cur_category = Mage::getModel(‘catalog/category’)->load($_category->getId());
        echo $cur_category->getData(‘claim’);

        endforeach;

        1. Buenas Ana,

          Siento decirte que estás aplicando una mala práctica de programación en el caso del desarrollo Magento. Es posible que ahora te funcione correctamente, pero en el momento crezcan un poco los datos vas a tener fallos de rendimiento. No se pueden añadir load dentro de una colección.

          Si consigues los datos con el load y no con la colección, efectivamente el problema que tienes es que en la colección no tienes añadido el atributo correspondiente, tienes que añadirlo a la colección, que dependiendo de la colección que sea te va a costar mas o menos.

          Espero haberte podido ayudar, cualquier cosa me comentas.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *