Crear una extensión para Magento

Crear una extensión para Magento

magento

Cuando hablamos de CMS preparados para tiendas, se nos vienen a la cabeza, por lo general, dos nombres: Magento y PrestaShop. Como la mayoría de CMS, es posible expandir sus funciones mediante el uso de extensiones o módulos. El caso que hoy nos ocupa es ese mismo, el de crear extensiones para Magento.

A traves de este tutorial, aprenderemos lo más básico de la creación de módulos para Magento: estructura de directorios, observadores, modelos y algunos trucos básicos. Este tutorial es el mismo que ofrecen los chicos de Smashing Magazine, podéis consultar el original en inglés si queréis. Nosotros os lo explicamos en español.

El tutorial consiste en hacer un módulo que monitorice los cambios que se realizan en los productos (al añadir o modificar).

Antes de empezar…

Asumimos que tienes una tienda Magento instalada y funcionando, y que, evidentemente, eres el administrador de la tienda. No importa qué versión de Magento tengas, sea de pago o sea gratis, ya que vamos a tocar aspectos muy básicos que no cambian de una a otra. Asumimos también que tienes conocimientos en PHP y XML.

Deshabilitando la caché

Lo primero es lo primero: Desactivar las opciones de caché de Magento. La caché es el enemigo numero uno del desarrollador de Magento. Si no lo hacemos, corremos el riesgo de quedarnos durante horas estancados en un punto, esperando a que Magento refresque su caché… una vez al día. Para ello, vamos a Sistema > Gestor de la caché, pulsamos en “Seleccionar todo” en la tabla arriba a la izquierda, y a la derecha vemos un desplegable en el que seleccionamos “Deshabilitar“. Pulsamos “Enviar“. Listo, caché deshabilitada, es un paso muy importante.

La estructura de directorios

Magento guarda sus módulos en la carpeta app/code. Esta carpeta se estructura de la siguiente forma:

  • /core: En esta carpeta están los módulos de sistema. Es su núcleo principal. Así que, salvo que queramos destrozar nuestro sistema Magento (hay gente para todo), tocar aquí es pecado mortal. Magento está preparado para aceptar cambios en estos módulos sin necesidad de editarlos directamente, de forma que si hay un error, el código original se mantiene. Por supuesto, es una buena práctica leer los contenidos de esta carpeta si queremos ver ejemplos de como funcionan los modulos, pero sin tocar nada. Se mira, pero no se toca.
  • /community: Aquí se alojan los módulos desarrollados por otras empresas ajenas a la organización de Magento. Por ejemplo, las aplicaciones que instalamos a través de Magento Connect van a parar aquí.
  • /local: Si no existe esta carpeta en tu sistema, por el poder que me ha sido otorgado al escribir este blog, te doy permiso para crearla. Por lo general, al instalar Magento se crea esta carpeta vacía (o bien, no se crea). Aquí es donde nosotros vamos a desarrollar nuestro módulo. Es la carpeta para desarrollar en nuestro sistema sin que se nos mezcle nuestra extensión con el resto y podamos encontrarla rápidamente. Trabajaremos aquí el resto del tutorial.

La estructura de un módulo

Ahora que ya sabemos dónde vamos a trabajar, necesitamos conocer cómo se estructura un módulo. Magento trabaja de una forma muy bien organizada a través de carpetas, que luego XML sabrá reconocer si el código está bien escrito. Para empezar, vamos a entrar en app/code/local.

Namespace

Dentro de app/code/local vamos a crear una carpeta. Por lo general, esta carpeta se debe llamar como nuestra organización, y actua como namespace (espacio de nombres, nos va a servir para diferenciar las extensiones que desarrollamos nosotros). Así, los plugins de Magento están en la carpeta Mage, por ejemplo. Nosotros vamos a crear la carpeta Codigonexo (vosotros podéis llamarla como queráis). Actualmente, nuestra ruta es app/code/local/Codigonexo. Podéis ponerle el nombre que queráis, pero solo letras: ni espacios, ni guiones bajos (esto es importante, los guiones bajos luego se utilizarán con otros fines, asi que aquí no podemos usarlos). Ah, el sistema es sensible a mayúsculas, así que luego estos nombres hay que respetarlos, salvo que se indique lo contrario.

Nombre del módulo

Dentro de la carpeta con nuestra compañía, vamos a crear otra carpeta, cuyo nombre es el nombre del módulo. Una buena práctica es usar nombres descriptivos. Como en este caso vamos a controlar los cambios hechos en productos, un buen nombre sería: ControlDeProductos. Lo mismo que antes, nada de espacios, ni de guiones bajos, y sensible a mayúsculas.

Nuestra ruta ahora mismo es app/code/local/Codigonexo/ControlDeProductos.

Configuración del módulo

Vamos ahora a crear el archivo de configuración del módulo, el que dará la versión del módulo y los observadores que contendrá. Dentro de ControlDeProductos, creamos la carpeta etc, y dentro de esta, el archivo config.xml. Este archivo contendrá el siguiente código:

<?xml version="1.0" encoding="UTF-8"?>

<!-- Nodo principal de la configuración de un módulo de Magento -->

<config>

	<!-- El nodo module contiene información básica sobre cada módulo de Magento -->
	<modules>

		<!--
			Esto debe coincidir exactamente con el nombre del namespace y el nombre del módulo,
			es decir, con la carpeta que contiene al módulo y la carpeta del módulo, separadas con un guion bajo
		-->
		<Codigonexo_ControlDeProductos>

			<!-- La versión del módulo. Empezamos en 0.0.1 -->
			<version>0.0.1</version>

		</Codigonexo_ControlDeProductos>

	</modules>

</config>

No hace falta que explique mucho más, ¿Verdad? Está todo en los comentarios del código.

Activando nuestro módulo

El siguiente paso le dirá a Magento que tiene un módulo nuevo y activo en la carpeta local y que debe entrar a leer su configuración. Esta vez, vamos a volver a la carpeta app. Navegamos hasta app/etc/modules, y creamos un nuevo archivo, llamado con el nombre del namespace y el del módulo: Codigonexo_ControlDeProductos.xml en nuestro caso.

<?xml version="1.0" encoding="UTF-8"?>

<config>

	<modules>

		<Codigonexo_ControlDeProductos>

			<!-- Indica si nuestro modulo está activo: true o false -->
			<active>true</active>

			<!-- Indica en qué directorio encontrará el módulo: core, community o local -->
			<codePool>local</codePool>

		</Codigonexo_ControlDeProductos>

	</modules>

</config>

Comprobación: ¿Está el módulo activo?

Actualmente, con lo que hemos hecho, ya tenemos un módulo funcionando en Magento. No hace nada, de acuerdo, pero está funcionando, y Magento debería reconocerlo. Para ello, vamos al administrador de Magento y pinchamos en Sistema > Configuración, en el menú izquierdo entramos en Avanzado (abajo del todo, en la subsección “Avanzado”, la última). Nos saldrá una página con un enlace “Disable Modules Output“. Al pinchar en el enlace, se desplegará la lista de módulos.

Si hemos hecho todos los pasos anteriores correctamente, nuestro módulo debería estar listado aquí. Si no lo está, entonces repasa bien el tutorial hasta aquí, mira cada punto, cada coma, cada guión bajo, cada signo de interrogación. Este suele ser el momento en que los desarrolladores descubren la antes mencionada caché de Magento…

Hasta el momento, nuestra estructura de carpetas es la siguiente:

app
|- code
|  |- local
|     |- Codigonexo
|        |- ControlDeProductos
|           |- etc
|              |- config.xml
|
|- etc
|  |- modules
|     |- Codigonexo_ControlDeProductos.xml

Definiendo un observador

Los observadores de eventos son muy potentes y son una de las maneras más limpias de extender las funcionalidades de magento sin tener que reescribir o sobrescribir ningún método o clase del núcleo. Como queremos observar el evento que se lanza justo después de guardar un producto, el código de evento que nos interesa es catalog_product_save_after. Determinar qué código de evento usar cuando definimos un observador requiere un conocimiento básico de la estructura de modelos de Magento, que escapa del objetivo de este tutorial. Pero hablaremos de ello en otra ocasión.

Volvamos a nuestro archivo config.xml y editemoslo un poquito:

<?xml version="1.0" encoding="UTF-8"?>

<config>
	<modules>
		<Codigonexo_ControlDeProductos>
			<version>0.0.1</version>
		</Codigonexo_ControlDeProductos>
	</modules>

	<!-- Configuramos el comportamiento del módulo dentro de global -->
	<global>

		<!-- Definimos un evento observador -->
		<events>

			<!-- Establecemos el código del evento que queremos observar -->
			<catalog_product_save_after>

				<!-- Aquí definimos el observador del evento -->
				<observers>

					<!--
						Este es el identificador único para el nodo catalog_product_save_after.
						Por convención, se escribe el nombre del módulo en minúsculas.
					-->
					<codigonexo_controldeproductos>

						<!-- El modelo a instanciar-->
						<class>codigonexo_controldeproductos/observer</class>

						<!-- El método de la clase a llamar-->
						<method>control</method>

						<!-- El tipo de clase a instanciar -->
						<type>singleton</type>

					</codigonexo_referals>

				</observers>

			</catalog_product_save_after>

		</events>

	</global>

</config>

Configurar el directorio de modelos

En el evento que hemos definido, hacemos referencia a un modelo que no existe aun. Tenemos que informar a Magento de su existencia, añadiendo el siguiente código a config.xml:

<?xml version="1.0" encoding="UTF-8"?>

<config>
	<modules>
		<Codigonexo_ControlDeProductos>
			<version>0.0.1</version>
		</Codigonexo_ControlDeProductos>
	</modules>

	<global>

		<!-- Definimos los modelos -->
		<models>

			<!--
				Identificador único para el nodo de modelos.
				Por convención, se escribe el nombre del módulo en minúsculas.
			-->
			<codigonexo_controldeproductos>

				<!--
					La ruta a nuestro directorio de modelos, separando
					los directorios con guiones bajos
				-->
				<class>Codigonexo_ControlDeProductos_Model</class>

			</codigonexo_controldeproductos>

		</models>

		<events>
			<catalog_product_save_after>
				<observers>
					<codigonexo_controldeproductos>
                                                <class>codigonexo_controldeproductos/observer</class>
                                                <method>control</method>
						<type>singleton</type>
					</codigonexo_controldeproductos>
				</observers>
			</catalog_product_save_after>
		</events>
	</global>
</config>

Creando el modelo del observador

Ahora sí, creamos el modelo que instanciaremos cuando el evento se dispare. Esto lo haremos en app/code/local/Codigonexo/ControlDeProductos/Model/Observer.php (correcto, tienes que crear la carpeta Model y el archivo Observer.php):

<?php

/**
 * Nuestra clase debe nombrarse siguiendo la estructura de nuestro
 * Observer.php, empezando desde el namespace, separando los directorios
 * con guiones bajos.
 */

class Codigonexo_ControlDeProductos_Model_Observer{
    /**
     * Magento pasa como primer parámetro de los eventos un Varien_Event_Observer
     */
     public function control(Varien_Event_Observer $observer){
         // Recupera el producto que está siendo actualizado desde el evento observador.
         $product = $observer->getEvent()->getProduct();

         // Escribe una nueva linea en var/log/product-updates.log
         $name = $product->getName();
         $sku = $product->getSku();
         Mage::log(
            "{$name} ({$sku}) updated",
            null,
            'product-updates.log'
         );
     }
}

?>

¡Ya está! Probemos que funciona

Antes de nada, recordarte que estamos haciendo uso de las funciones de “logs” de Magento. Por defecto, estas opciones están deshabilitadas, así que deberías mirar que están habilitadas en Sistema > Configuración > Desarrollador (de nuevo, abajo del todo), pulsar en “Log Settings” y establecer “Habilitado” en (y finalmente, pulsar en Guardar la configuración), así como comprobar los permisos de las carpetas de Magento.

Nuestra estructura final de carpetas es esta:

app
|- code
|  |- local
|     |- Codigonexo
|        |- ControlDeProductos
|           |- Model
|           |  |- Observer.php
|           |
|           |- etc
|              |- config.xml
|
|- etc
   |- modules
      |- Codigonexo_ControlDeProductos.xml

Para comprobar que nuestro módulo funciona, podemos añadir un nuevo producto o modificar uno existente. En la carpeta var/log de nuestro Magento, ha debido aparecer un archivo llamado product-updates.log. Si lo abrimos, veremos los cambios que hemos realizado en nuestro producto.

Con lo que hemos aprendido hoy, tenemos una idea básica de cómo funciona Magento por dentro. Es buena idea, como ya dije al principio, leer cómo están hechos otros módulos para ver otros ejemplos de uso de observadores y modelos.

¡No dejes de leer la siguiente parte del tutorial: Añadir páginas desde una extensión!

“Nos estamos ahogando en información,
pero estamos hambrientos de conocimiento”
— John Naisbitt

¿Te ha gustado el artículo?
1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (1 votos, promedio: 5,00 sobre 5)
Loading...
Artículo escrito por

¡Exprésate! Dejanos tu comentario

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

11 Comentarios

Lis

Super tutorial, tuve algunos lios pero fueron externos y fue en los permisos de escritura en la carpeta var para que creara los logs en su respectiva ruta, tengo una pregunta, si quisiese implementar esta misma estructura para crear los logs de igual manera pero que registrara cambios que realice el administrador en cualquier parte del panel administrativo, es posible, existe manera ??? agradezco cualquier info.

Diseño web

Buenas! Muy útil el articulo y muy bien explicado, solo con un matiz, podrias haber indicado la versión de magento para la que trabajas ya que los events depende mucho de esto. Por ejemplo en 1.7 ese event no existe. Gran trabajo!

David77

Hola Ruben queria darte las gracias enormes por  explicar tan bien de todo corazon un gran abrazo y felicitaciones, tambien me gustaria saber si tienes un ejemplo que incluya el template o algo asi gracias nuevamente

Johnb218

It's a mammoth playground built of mountains, hills, lakes, rivers, valleys, woodlands,and beaches. kbbgcgedcfff

Johng95

Hello my family member! I want to say that this article is amazing, great written and come with almost all significant infos. Id like to peer extra posts like this . geedfddgdgkg

Johnb144

insecticide permethrin side effects in cats ddffkagabeak

bryan

hola me gusto el tutorial no se si tendras un tutorial de como comenzar  a editar magento desde cero , developer. Saludos desde peru,

jose cruz chavez

Buenas tardes, tu tutorial es genial, muy bien explicado, muy limpio y claro, gracias por compartir.

javierq

Excelente el post. Gracias por compartir. Una pregunta. Yo trabajo en una tienda y tenemos un buscador para hacer las búsquedas de los productos, pero funciona de pena, con lo cual quería hacer un módulo para mejorar el buscador por defecto. A este tipo de añadidos se les denomina módulos o APIs. Para programar uno necesito php y xml, o con php ya podría hacerlo.   Muchas gracias.  

Edu

Hola podrías hacer un tuto para crear una extensión para validar si un correo ya existen en la base de datos, pero que muestre ese mensaje en tiempo real, creo que sería mediante json, usando prototype y esas cosas. muy buen tutorial Saludos

salva

Hola, muchas gracias por escribir el tutorial, está muy bien y bien explicado. Saludos