Publi

Creando un modelo sencillo en Magento (paso a paso y con ejemplos)

Anteriormente vimos cómo crear un plugin para Magento y cómo crear un controlador para Magento. Ahora le toca el turno al modelo. Intentaré poner con todo detalle todo el proceso.
Por eso, vamos a editar app/code/local/NuestraEmpresa/nuestroPlugin/etc/config.xml, en nuestro ejemplo app/code/local/Poesia/HolaMundo/etc/config.xml para indicar que vamos a crear modelos y las conexiones de base de datos que se deben utilizar para el acceso. He pegado el archivo entero, pero indico con un comentario las novedades:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?xml version="1.0" encoding="UTF-8"?>
<!--
Opcionalmente podemos poner un comentario contando qué hace nuestro módulo, nuestra web,
información sobre la licencia, etc
-->
<config>
    <modules>
        <Poesia_HolaMundo> <!-- namespace_modulo -->

            <!-- Esta es la versión de nuestro módulo -->
            <version>0.0.1</version>

        </Poesia_HolaMundo>
    </modules>

    <frontend>
      <!-- Lo que necesitamos para utilizar los controladores -->
      <routers>
    <holaMundo>
      <use>standard</use>
      <args>
        <module>Poesia_HolaMundo</module>
        <frontName>hm</frontName>
      </args>
    </holaMundo>
      </routers>
      <!-- Lo que necesitamos para utilizar los controladores -->
      <!-- Lo que necesitamos para el layout y las plantillas -->
      <layout>
    <updates>
      <holamundo>
        <file>poesia.xml</file>
      </holamundo>
    </updates>
      </layout>
      <!-- Lo que necesitamos para el layout y las plantillas -->
    </frontend>
    <!-- Necesario para informar a Magento sobre nuestro modelo -->
    <global>
      <models>
    <holamundo>
        <class>Poesia_Holamundo_Model</class>
        <resourceModel>holamundo_resource</resourceModel>
    </holamundo>
    <holamundo_resource>
        <class>Poesia_HolaMundo_Model_Resource</class>
        <entities>
        <pventamod>
            <table>poesia_postvtable</table>
        </pventamod>
        </entities>
    </holamundo_resource>
      </models>
      <resources>
        <holamundo_setup>
          <setup>
            <module>Poesia_HolaMundo</module>
          </setup>
          <connection>
            <use>core_setup</use>
          </connection>
        </holamundo_setup>
        <holamundo_write>
          <connection>
            <use>core_write</use>
          </connection>
        </holamundo_write>
        <holamundo_read>
          <connection>
            <use>core_read</use>
          </connection>
        </holamundo_read>
      </resources>

    </global>
    <!-- Necesario para informar a Magento sobre nuestro modelo -->
</config>

Ahora creamos el modelo (le intento dar a todo nombres diferentes para que veamos qué es cada cosa). Más o menos esto son algunas definiciones básicas para empezar a trabajar.
[modelo y todo eso luego]

Creamos la tabla en la base de datos

Aunque se puede hacer todo directamente, yo prefiero crear la tabla a mano primero para ir haciendo pruebas y asegurarme de que todo va funcionando bien. Más adelante crearemos un script que se encargará de generar la tabla, pero, por ahora la crearemos a mano en MySQL para asegurarnos de que todo encaja. Supondremos que el prefijo de las tablas de Magento es «mage_», que viene por defecto, lo podemos ver en app/etc/local.xml (config.global.resources.db.table_prefix). Lo siguiente, lo ejecutaremos directamente en nuestro servidor de base de datos, ya sea por consola, o a través de PHPMyAdmin o similares.

1
2
3
4
5
6
7
CREATE TABLE mage_poesia_postvtable (
   table_id BIGINT NOT NULL AUTO_INCREMENT,
   user_id BIGINT,
   user_email VARCHAR(192),
   comment TEXT,
   PRIMARY KEY(table_id)
) ENGINE=InnoDB DEFAULT CHARSET='UTF8';

Como en el XML dijimos que el nombre de la tabla era poesia_postvtable, le ponemos el prefijo delante al crearla.

Y como estamos probando y sólo queremos algunos datos sin sentido para saber que todo va bien:

1
2
3
INSERT INTO mage_poesia_postvtable VALUES (NULL, 1, 'usuario1@servidor.ext', 'Never forget the WHERE');
INSERT INTO mage_poesia_postvtable VALUES (NULL, 100, 'user2@server.ext', 'What does the fox say?');
INSERT INTO mage_poesia_postvtable VALUES (NULL, 123, 'usuario3@server.ext', 'The day the routers die');

Crear estructura de ficheros del modelo

Ahora toca el turno de crear ficheros y directorios. Para ello, vamos a crear dentro del directorio de nuestro plugin el siguiente árbol de directorios (en mi caso app/code/local/Poesia/HolaMundo/):

  • Model (aquí irán todos los modelos)
    • Resource (dentro de los modelos tendremos los recursos)
      • Pventamod (será el correspondiente al modelo que vamos a hacer)

Ahora crearemos los archivos necesarios para utilizarlos:
app/code/local/Poesia/HolaMundo/Model/Pventamod.php

1
2
3
4
5
6
7
8
9
<?php

class Poesia_HolaMundo_Model_Pventamod extends Mage_Core_Model_Abstract
{
  public function _construct()
  {
    parent::_construct();
    $this->_init('holamundo/pventamod');
  }

app/code/local/Poesia/HolaMundo/Model/Resource/Pventamod.php

1
2
3
4
5
6
7
8
<?php
class Poesia_HolaMundo_Model_Resource_Pventamod extends Mage_Core_Model_Resource_Db_Abstract
{
  protected function _construct()
  {
    $this->_init('holamundo/pventamod', 'table_id');
  }
}

app/code/local/Poesia/HolaMundo/Model/Resource/Pventamod/Collection.php

1
2
3
4
5
6
7
8
9
10
<?php

class Poesia_HolaMundo_Model_Resource_Pventamod_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
{
  public function _construct()
  {
    parent::_construct();
    $this->_init('holamundo/pventamod');
  }
}

¡¡Ya está listo nuestro modelo!!

Archivo xml de layout

Aquí coloco el archivo poesia.xml que debe situarse en app/design/frontend/default/default/layout/poesia.xml (en lugar de default/default se puede particularizar para un tema en concreto):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0"?>
<layout version="0.1.0">
  <default>
    <reference name="head">
      <!-- CSS y JS propios -->
      <action method="addJs">
        <script>holamundo/holamundo.js</script> <!-- se buscará en [magentoroot]/js -->
      </action>

      <action method="addCss">
    <!-- se buscará en [magentoroot]/skin/frontend/default/[tema]/css/ -->
    <!-- o en [magentoroot]/skin/frontend/base/default/css/ -->
        <stylesheet>css/holamundo.css</stylesheet>
      </action>
    </reference>
    <reference name="root">
      <action method="setTemplate">
    <template>page/1column.phtml</template>
      </action>
    </reference>
  </default>
  <holamundo_postventa_index>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/index.phtml"></block>
    </reference>
  </holamundo_postventa_index>
  <holamundo_postventa_test>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/test.phtml"></block>
    </reference>
  </holamundo_postventa_test>
</layout>

Haciendo algo con el modelo

Ya podemos empezar a trabajar con nuestro modelo (no vamos a entrar en detalle en la utilización del ORM de Magento), por ejemplo, consultando información. Para ello, vamos a utilizar una vista (podemos utilizar una vista de nuestro controlador (holamundo), y hacer lo siguiente:
app/design/frontend/base/default/template/holamundo/test.phtml

1
2
3
4
5
6
7
8
9
10
<p>Ejemplo de vista de TEST</p>
<?php
    $model = Mage::getmodel('holamundo/pventamod');
    $primero = $model->load(1);
    echo get_class($primero);
    echo "ID: ". $primero->getTableId()."<br/>";
    echo "Userid: ".$primero->getUserId()."<br/>";
    echo "Email: ".$primero->getUserEmail()."<br/>";
    echo "Comentario: ".$primero->getComment()."<br/>";
?>

También copio app/design/frontend/base/default/template/holamundo/index.phtml, aunque para esta prueba sólo contendrá:

1
<p>¡¡¡¡¡¡¡¡¡¡¡¡¡ soy el index !!!!!!!!!!!!!</p>

Auto-creación de tablas

Para facilitar al usuario a la hora de instalar plugins, facilitar las actualizaciones cuando las pasamos a producción y agilizar todo el proceso. Consiste en una serie de scripts para crear y actualizar la base de datos, que nos permitirá ejecutar cualquier sentencia SQL ante la presentación de una determinada versión de nuestro plugin.

Vamos a crear, dentro del directorio de nuestro plugin, el directorio sql, y dentro de éste holamundo_setup (igual que estaba puesto bajo resources en nuestro config.xml). Dentro crearemos un archivo llamado install-0.0.1.php (0.0.1 es la versión de nuestro plugin, que la pusimos cuando creamos el config.xml).

Nuestro archivo app/code/local/Poesia/HolaMundo/sql/holamundo_setup/install-0.0.1.php será el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

$installer = $this;

$installer->startSetup();

$installer->run("

CREATE TABLE IF NOT EXISTS `{$this->getTable('poesia_postvtable')}`(
   table_id bigint NOT NULL AUTO_INCREMENT,
   user_id BIGINT,
   user_email VARCHAR(192),
   comment TEXT,
   PRIMARY KEY(table_id)
) ENGINE=InnoDB DEFAULT CHARSET='utf8';
    "
);

$installer->run("INSERT INTO `{$this->getTable('poesia_postvtable')}`
   VALUES (NULL, 10, 'email@email.com', 'comentario de prueba')"
);

$installer->endSetup();

Podemos ver que para colocar el nombre de la tabla utilizamos $this->getTable(), esta función incluirá el nombre de la tabla con el prefijo del sistema. No es obligatorio poner un INSERT, yo lo he puesto para que el ejemplo funcione directamente.

Para comprobar que este script se ejecuta, sólo en pruebas, podemos introducir un die(‘Me ejecuto’) al principio del archivo de instalación. Así veremos que todo marcha bien.

Si vemos que, aunque borrando la base de datos, no se carga el script de instalación, podemos forzarlo haciendo que el sistema olvide nuestro plugin, accediendo a la base de datos y buscando la tabla «mage_core_resource» (de nuevo supongo que vuestro prefijo es mage_), ahí podemos hacer lo siguiente:

mysql [localhost] (magento) > SELECT * FROM mage_core_resource WHERE code LIKE ‘%holamundo%’;
+—————–+———+————–+
| code | version | data_version |
+—————–+———+————–+
| holamundo_setup | 0.0.1 | 0.0.1 |
+—————–+———+————–+
1 row in set (0.00 sec)

mysql [localhost] (magento) > DELETE FROM mage_core_resource WHERE code LIKE ‘%holamundo%’;
Query OK, 1 row affected (0.00 sec)

Tened cuidado por si borráis algo necesario, aquí sólo estamos borrando nuestro plugin, pero si hay algún plugin más, debemos utilizar su nombre completo.

Ahora cuando recarguemos alguna página de Magento, el plugin se instalará y de nuevo podremos ver la tabla en nuestra base de datos (y empezar a operar con ella). Si de hecho es la primera vez que esto se ejecuta en esta instalación de Magento, esto será transparente para el usuario.

Actualizando plugins en la base de datos

Cuando actualizamos un plugin que hemos creado, es común cambiar cosas en las tablas, imaginemos que hemos metido un campo más en la tabla, variado longitudes de campo, añadido claves, etc. Para eso tenemos los scripts de actualización. De la misma forma que los scripts de instalación, éstos estarán situados en app/code/local/NombreEmpresa/NombrePlugin/sql/recurso_setup/ y tendrán como nombre «upgrade-[versión.antigua]-[versión_nueva].php.

Ahora, nuestro plugin lo actualizamos a la versión 0.2.0 (antiguamente tenía la 0.0.1) entonces crearemos un script llamado:
app/code/local/Poesia/HolaMundo/sql/holamundo_setup/upgrade-0.0.1-0.2.0.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php

$installer = $this;

$installer->startSetup();

$installer->run("

ALTER TABLE `{$this->getTable('poesia_postvtable')}`
   ADD COLUMN tipo BIGINT NOT NULL;"
);

$installer->endSetup();

y con esto añadimos la columna tipo que podremos utilizar a partir de este instante.

Actualizado el 23/01/2017: Gracias a Alex coloco un archivo que me he dejado (poesia.xml). Ya podéis copiar y pegar por completo el plugin de prueba 🙂

Foto: Susana Fernandez (Flickr CC-By)

También podría interesarte....

There are 18 comments left Ir a comentario

  1. Pingback: Creando un modelo sencillo en Magento (paso a paso y con ejemplos) | PlanetaLibre /

  2. Samuel /
    Usando Google Chrome Google Chrome 43.0.2357.81 en Windows Windows NT

    muy interesante los tutoriales, se le agradece un monton, porque no hay mucha informacion en español, espero que pueda actuazar otro para seguir con el ilo

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 38.0 en Ubuntu Linux Ubuntu Linux

      Muchas gracias, poco a poco a medida que vaya trabajando más con Magento iré completando estas guías.

  3. Samuel /
    Usando Google Chrome Google Chrome 43.0.2357.81 en Windows Windows NT

    Disculpe la molestia, no se si nos puede brindar el codigo para revisarlo, porque e tratatado de hacerlo igual, pero no me funciona, espero nos pueda ayudar

  4. Samuel /
    Usando Google Chrome Google Chrome 45.0.2454.101 en Windows Windows NT

    ya logre que me funcionara. muchas gracias por su gran aporte

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 41.0 en Ubuntu Linux Ubuntu Linux

      Muchas gracias !! Me alegra muchísimo que te haya servido.

  5. Alex /
    Usando Google Chrome Google Chrome 55.0.2883.87 en Windows Windows 7

    te has dejado el poeasia.xml sin mostrar, no se como acceder al template

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 50.0 en Ubuntu Linux Ubuntu Linux

      Llevas toda la razón. ¡Voy a colocarlo ahora mismo!

      1. Alex /
        Usando Google Chrome Google Chrome 55.0.2883.87 en Windows Windows 7

        Muchas Gracias por el aporte, me ha sido de gran ayuda.

        Actualmente estoy investigando Magento para un proyecto de mi empresa y estos aportes son de verdadera ayuda.

        Muchisimas gracias.

        1. Gaspar Fernández / Post Author
          Usando Mozilla Firefox Mozilla Firefox 50.0 en Ubuntu Linux Ubuntu Linux

          Gracias a ti. Me alegro de que sean de ayuda. Espero poder meterme pronto con Magento 2 ! 🙂

          1. Alex /
            Usando Google Chrome Google Chrome 55.0.2883.87 en Windows Windows 7

            Perdona que te moleste Gaspar, pero a ver si puedes resolverme esta duda sobre Magento (Te vas a dar cuenta que soy muy nuevo).

            Estoy creandome un script installer para que al instalar el plugin que estoy creando se añadan campos a la base de datos de magento.

            Para ser mas directo quiero añadirle un nuevo atributo a un usuario, el atributo «Gemas» Esto se añade en las tablas eav_attribute y customer_entity_varchar, el problema es al hacerlo desde el installer.

            De momento tengo esto:

            $installer = $this;

            $installer->startSetup();

            $installer->run(»

            CREATE TABLE IF NOT EXISTS `{$this->getTable(‘mage_poesia_postvtable’)}`(
            table_id bigint NOT NULL AUTO_INCREMENT,
            user_id BIGINT,
            user_email VARCHAR(192),
            comment TEXT,
            PRIMARY KEY(table_id)
            ) ENGINE=InnoDB DEFAULT CHARSET=’utf8′;
            «);

            $installer->run(«INSERT INTO `{$this->getTable(‘eav_attribute’)}`»
            . «(`entity_type_id`, `attribute_code`, `backend_type`, `frontend_input`, `frontend_label`, `is_required`, `is_user_defined`, `is_unique`)»
            . » VALUES (1,’gemas’,’varchar’,’text’,’Gemas’,0,0,0)»);

            $installer->run(«INSERT INTO `{$this->getTable(‘customer_entity_varchar’)}`( `entity_type_id`, `attribute_id`, `entity_id`, `value`) VALUES (1,132,1,500)»);

            $installer->endSetup();

            El problema es al añadir la row en customer_entity_varchar que el attribute_id es el de la row que he añadido arriba y no se como sacar esa id.

            Alguna idea compañero?

            Gracias por todo.

            Alex

  6. Gaspar Fernández / Post Author
    Usando Mozilla Firefox Mozilla Firefox 50.0 en Ubuntu Linux Ubuntu Linux

    Hola Alex,

    Prueba una cosa, espero que te funcione:

    1
    $installer->run(“INSERT INTO `{$this->getTable(‘customer_entity_varchar’)}`( `entity_type_id`, `attribute_id`, `entity_id`, `value`) VALUES (1,LAST_INSERT_ID(),1,500));

    Si necesitas algo más complicado, una vez creadas las tablas pertinentes puedes utilizar los modelos con Mage::getModel(), y creo recordar que había métodos para hacer esos inserts de forma más limpia.

    1. Alex /
      Usando Google Chrome Google Chrome 55.0.2883.87 en Windows Windows 7

      Perfecto, funciona!

      Muchas gracias, eres un crack!

      Seguire mirandome el tema de los getModel() que dices, pero lo que no entiendo muy bien es como sabes el nombre del modelo que quieres, si por ejemplo quiero la tabla customers_entity_varchar como puedo coger el modelo de esa tabla?

      Bueno muchas gracias por todo!

      1. Gaspar Fernández / Post Author
        Usando Mozilla Firefox Mozilla Firefox 50.0 en Ubuntu Linux Ubuntu Linux

        Yo siempre que tengo que buscar un modelo, intento buscar el módulo donde está definido y luego busco el archivo donde está el modelo. Luego puedes hacer getModel(‘modulo/modelo’) no siempre es así. El nombre del modelo no es tan claro y tienes que mirar los archivos XML del módulo (Magento es así, con muchos XML por todas partes).

        Pero el tema de los atributos, como otras cosas en Magente es especial. Un mismo modelo atacará a varias tablas, por eso de la estructura EAV que tiene este sistema.

        He encontrado un sitio que tal vez te ayude: http://blog.chapagain.com.np/magento-adding-attribute-from-mysql-setup-file/ con esto puedes crear atributos nuevos sin pelearte con base de datos.

        1. Alex /
          Usando Google Chrome Google Chrome 55.0.2883.87 en Windows Windows 7

          Genial muchas gracias por todo! Gran aporte y ayuda

Leave a Reply