Tabla de contenidos
Table of Contents | ||
---|---|---|
|
...
Creación de un módulo de PrestaShop
...
Quizás el interés principal de un módulo es agregar funciones a PrestaShop sin tener que editar sus archivos principales, haciéndolo más fácil para realizar una actualización sin necesidad de transponer todos los cambios fundamentales.
Esa es la forma en que deben debe tratar de mantenerse alejado de los archivos centrales cuando construya un módulo, aunque esto puede resultar difícil de realizar en algunas situaciones...
...
El archivo mymodule.php
debe comenzar con la siguiente prueba:
Code Block |
---|
if ( !defined( '_PS_VERSION_' ) )
exit;
|
Esto comprueba la existencia de una constante de PHP, y si no existe, abandona. El único propósito de esta prueba es evitar que los visitantes cargauen carguen este archivo directamente.
...
Esa clase debe tener el mismo nombre que el módulo y su carpeta, en CamelCase: MyModule
.
Por otra parte, la clase debe extender la clase Module
y por lo tanto hereda todos los métodos y atributos. Esta puede igualmente extender cualquier clase derivada del Module
: PaymentModule
, ModuleGridEngine
, ModuleGraph
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?php
if ( !defined( '_PS_VERSION_' ) )
exit;
class MyModule extends Module
{
public function __construct()
{
$this->name = 'mymodule';
$this->tab = 'Test';
$this->version = 1.0;
$this->author = 'Firstname Lastname';
$this->need_instance = 0;
parent::__construct();
$this->displayName = $this->l( 'My module' );
$this->description = $this->l( 'Description of my module.' );
}
public function install()
{
if ( parent::install() == false )
return false;
return true;
}
}
?>
|
Vamos a examinar cada línea de nuestro objeto MyModule
...
Code Block |
---|
public function __construct()
|
Define el constructor de clase.
Code Block |
---|
$this->name = 'mymodule';
$this->tab = 'Test';
$this->version = 1.0;
$this->author = 'PrestaShop';
|
En esta Esta sección asigna unos cuantos atributos de la instancia de clase (this
):
- Un atributo 'name'. Este es un identificador interno, así que hágalo único, sin caracteres especiales o espacios, y en minúsculas.
- Un atributo 'tab'. Este es el título del cuadro que deberá contener este módulo en la lista de módulos del back office de PrestaShop. Usted puede utilizar un nombre ya existente, como
Products
,Blocks
orStats
, o uno personalizado, como lo hicimos aquí. En este último caso, un nuevo cuadro se ha creado con su título. - Número Un número de versión para el módulo, aparece en la lista de módulos.
- Un atributo 'author'. Este se muestra en la lista de módulos de PrestaShop.
Code Block |
---|
$this->need_instance = 0;
|
La bandera need_instance
indica si se debe cargar la clase del módulo cuando se muestran los "Módulos", en la el back-office. Si se establece en 0, el módulo no cargará, por lo tanto gastará menos recursos para generar el módulo de página. Si sus módulos necesitan mostrar un mensaje de advertencia en la página "Módulos", entonces debe establecer este atributo en 1.
Code Block |
---|
parent::__construct();
|
Llamar al constructor del padre. Esto se debe realizar antes de cualquier uso del método $this->l()
y después de la creación de $this->name
.
Code Block |
---|
$this->displayName = $this->l( 'My module' );
|
Asignar un nombre público para el módulo, el cual será mostrado en la lista de módulos de back-office.
El método l()
es parte de las herramientas de traducción de PrestaShop, y se explica más adelante.
Code Block |
---|
$this->description = $this->l( 'Description of my module.' );
|
Asignación de una descripción pública para el módulo, la cual se mostrará en la lista de módulos del back-office.
Code Block |
---|
public function install()
{
return ( parent::install() );
}
|
En esta primera encarnación extremadamente simple, este método no es útil, ya que lo único que realiza es comprobar el valor devuelto por el método install() class de Módulo. Además, si no hubiéramos creado este método, el método superclase hubiera sido llamado en su lugar de todas formas, logrando que el resultado final sea idéntico.
Sin embargo, debemos mencionar que este método , ya que será muy útil una vez que tengamos que realizar las pruebas y acciones durante el proceso de instalación del módulo: crear cuadros tablas de SQL, copiar archivos, crear variables de configuración, etc.
Asimismo, el módulo debe contener un método uninstall()
para contar con un proceso de desinstalación personalizado. Este método podría realizarse algo así como:
Code Block |
---|
public function uninstall()
{
if ( !parent::uninstall() )
Db::getInstance()->Execute( 'DELETE FROM `' . _DB_PREFIX_ . 'mymodule`' );
parent::uninstall();
}
|
Para poner "el toque final" a este módulo básico, podemos agregar un icono, que se mostrará junto al nombre del módulo en la lista de módulos de back-office.
El archivo de icono debe respetar los siguientes requisitos:
- imágenes 16*16.
- llamado nombrado
logo.gif
. - colocado en la carpeta principal del módulo.
Puede encontrar un excelente conjunto de iconos gratuitus para elegir en el sitio web de FamFamFam..
Ahora que todos los fundamentos están en su lugar, coloque la carpeta del módulo en la carpeta /modules
de su instalación de prueba de PrestaShop, abra PrestaShop, y en la pestaña "Módulos", bajo "Otros módulos", debería encontrar su módulo. Instálelo para ser capaz de manejarlo por el resto de esta guía.
...
Durante la instalación, PrestaShop también agrega una línea al cuadro de SQL ps_module
.
Conexión de un módulo
...
a través de Hooks
Para que un módulo sea "atadoconectado" o "enganchado" a una ubicación en el front y back office, necesita ofrecerle acceso a uno de los hooks de PrestaShop, descritos anteriormente en esta guía.
En ese caso, cambiaremos el código del módulo, y agregaremos estas líneas:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public function install()
{
if ( parent::install() == false OR !$this->registerHook( 'leftColumn' ) )
return false;
return true;
}
...
public function hookLeftColumn( $params )
{
global $smarty;
return $this->display( __FILE__, 'mymodule.tpl' );
}
public function hookRightColumn( $params )
{
return $this->hookLeftColumn( $params );
}
|
Vamos a explorar estas nuevas líneas.
Code Block |
---|
if ( parent::install() == false OR !$this->registerHook( 'leftColumn' ) )
return false;
return true;
|
...
Por lo tanto, esta línea ahora se lee de esta manera: si la instalación o el “enganche” "enganche" fracasa, nosotros informamos informaremos a PrestaShop.
Code Block |
---|
public function hookLeftColumn( $params )
{
global $smarty;
return $this->display(__FILE__, 'mymodule.tpl');
}
|
El método hookLeftColumn()
hace posible que el módulo se “enganche” "enganche" en la columna izquierda del tema.
$smarty
es la variable global para el sistema de plantillas Smarty, el cual utiliza PrestaShop y que tenemos que acceder.
El método display()
devuelve el contenido del archivo de plantilla mymodule.tpl
, si es que existe.
Code Block |
---|
public function hookRightColumn( $params )
{
return $this->hookLeftColumn( $params );
}
|
...
Warning |
---|
Es inútil tratar de conectar un módulo a un hook para el que cual no tiene ningún método implementado. |
...
Por consiguiente, crearemos el archivo mymodule.tpl
y le agregaremos algunas líneas de código.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<!-- Block mymodule -->
<div id="mymodule_block_left" class="block">
<h4>Welcome!</h4>
<div class="block_content">
<ul>
<li><a href="{$base_dir}modules/mymodule/mymodule_page.php" title="Click this link">Click me!</a></li>
</ul>
</div>
</div>
<!-- /Block mymodule -->
|
...
Tip |
---|
Debe esforzarse por utilizar nombres explícitos y reconocibles para sus archivos TPL, para que pueda encontrarlos rápidamente en el back-office – los que son una necesidad cuando se utiliza la herramienta de traducción. |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
Welcome to my shop!
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?php
global $smarty;
include( '../../config/config.inc.php' );
include( '../../header.php' );
$smarty->display( dirname(__FILE__) . '/mymodule_page.tpl' );
include( '../../footer.php' );
?>
|
...
Tip |
---|
Si realiza múltiples cambios y recargas a su página de inicio, puede parecer que dichos cambios no son aplicados. Esto se debe a que Smarty almacena una versión compilada de la página de inicio. Para forzar Smarty a recompilar plantillas en cada invocación, trasládese diríjase a la sub-pestaña de “Rendimiento” en la pestaña de "Preferencias" y elija "Sí" en la opción "Forzar la compilación". ¡No fuerce la compilación en sitios de producción, ya que retrasa todo gravemente! |
...
Por ejemplo, en nuestro mymodule_page.php
, podemos crear una variable:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?php
global $smarty;
include( '../../config/config.inc.php' );
include( '../../header.php' );
$mymodule = new MyModule();
$message = $mymodule->l( 'Welcome to my shop!' );
$smarty->assign( 'messageSmarty', $message ); // creation of our variable
$smarty->display( dirname(__FILE__) . '/mymodule_page.tpl' );
include( '../../footer.php' );
?>
|
A partir de ahí, podemos pedir a Smarty que muestre el contenido de esta variable en nuestro archivo TPL.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{$messageSmarty}
|
PrestaShop incluye una serie de variables. Por ejemplo, {$HOOK_LEFT_COLUMN} será remplazado por el contenido de la columna izquierda, es decir, el contenido de todos los módulos que han sido unidos al hook de la columna izquierda.
...
Archivo / carpeta | Descripción |
---|---|
img_ps_dir | URL de la carpeta de imágenes de PrestaShop. |
img_cat_dir | URL de la carpeta de imágenes de categorías de imágenes. |
img_lang_dir | URL de la carpeta de imágenes de idiomas. |
img_prod_dir | URL de la carpeta de imágenes de productos. |
img_manu_dir | URL de la carpeta de imágenes de los fabricantes. |
img_sup_dir | URL de la carpeta de imágenes de los proveedores. |
img_ship_dir | URL de la capeta de las imágenes de los transportistas. |
img_dir | URL de la carpeta de las imágenes del tema. |
css_dir | URL de la carpeta del tema CSS. |
js_dir | URL de la carpeta del tema JavaScript. |
tpl_dir | URL de la carpeta del tema actual. |
modules_dir | URL de la carpeta de módulos. |
mail_dir | URL de la carpeta de plantillas de correo. |
pic_dir | URL de la carpeta de las fotos subidas. |
lang_iso | Código ISO del idioma actual. |
come_from | URL de origen del visitante. |
shop_name | Nombre de la tienda. |
cart_qties | Número de productos en el carrito. |
cart | El carro carrito de compras. |
currencies | Las monedas disponibles. |
id_currency_cookie | ID de la moneda actual. |
currency | Objeto de monedas moneda (moneda utilizada actualmente). |
cookie | Cookies de usuario. |
languages | Los diferentes idiomas disponibles. |
logged | Indica si el visitante se ha conectado a una cuenta de cliente. |
page_name | Nombre de la página. |
customerName | Nombre del cliente (si está conectado). |
priceDisplay | Método de visualización del precio(con o sin impuestos...). |
roundMode | Método de redondeo en uso. |
use_taxes | Indica si los impuestos se encuentran habilitados. |
Si necesita que se muestren todas las páginas actuales de variables de Smarty, agregue la siguiente función:
Code Block |
---|
{debug}
|
Los comentarios se basan en asterisco:
Code Block |
---|
{* This string is commented out *}
{*
This string is too!
*}
|
...
Las cadenas en los archivos PHP necesitarán ser mostradas a través del método l()
, de la clase abstracta Module.php
.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
...
$this->displayName = $this->l( 'My module' );
$this->description = $this->l( 'Description of my module.' );
...
|
Las cadenas en los archivos TPL tendrán que ser convertidas en contenido dinámico, que Smarty remplazará por la traducción del idioma elegido. En nuestro módulo de muestra, este archivo:
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<li>
<a href="{$base_dir}modules/mymodule/mymodule_page.php" title="Click this link">Click me!</a>
</li>
|
...se convierte en:
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<li>
<a href="{$base_dir}modules/mymodule/mymodule_page.php" title="{l s='Click this link' mod='mymodule'}">{l s='Click me!' mod='mymodule'}</a>
</li>
|
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<h4>Welcome!</h4>
...
Click me!
|
...se convierte en:
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
<h4>{l s='Welcome!' mod='mymodule'}</h4>
...
{l s='Click me!' mod='mymodule'}
|
...
Tip |
---|
Cada campo tiene un icono a la derecha. Esto le permite obtener una sugerencia del Traductor de Google. Puede desplazar el ratón sobre él para ver la traducción y haga clic en él para rellenar el campo con la traducción. La traducción automática traducciones automáticas no siempre son exactas, use con precaución. |
Las traducciones se guardan en un archivo nuevo, es.php
(o languageCode.php
, el cual es generado por PrestaShop y luce así:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?php
global $_MODULE;
$_MODULE = array();
$_MODULE['<{mymodule}prestashop>mymodule_2ddddc2a736e4128ce1cdfd22b041e7f'] = 'Mon module';
$_MODULE['<{mymodule}prestashop>mymodule_d6968577f69f08c93c209bd8b6b3d4d5'] = 'Description de mon module';
$_MODULE['<{mymodule}prestashop>mymodule_c66b10fbf9cb6526d0f7d7a602a09b75'] = 'Cliquez sur ce lien';
$_MODULE['<{mymodule}prestashop>mymodule_f42c5e677c97b2167e7e6b1e0028ec6d'] = 'Cliquez-moi \!';
$_MODULE['<{mymodule}prestashop>mymodule_page_c0d7cffa0105851272f83d5c1fe63a1c'] = 'Bienvenue dans ma boutique \!';
|
...
Y podrán ser traducidas al español cuando el Back Office está se encuentre en español.
Tip |
---|
TLas Sólo las cadenas traducidas sólo pueden ser son tomadas en cuenta por la herramienta de PrestaShop, los archivos de PHP y TPL deben ser ubicados en la raíz de la carpeta del módulo. |
...
En esta sección usted aprenderá cómo ofrecer a su módulo, su propia pestaña o sub-pestaña en cuestión de minutos.
...
- Agregar un nuevo cuadro a su base de datos de PrestaShop, llamado
ps_test
. Dele Ofrézcale dos campos:id_test
(INT 11)test
(VARCHAR 32)
- Crear un archivo en blanco llamado
Test.php
en la carpeta/classes
de PrestaShop. - Agregar las siguientes líneas a este archivo:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?php
class Test extends ObjectModel
{
/** @var string Name */
public $test;
protected $fieldsRequired = array( 'test' );
protected $fieldsSize = array( 'test' => 64 );
protected $fieldsValidate = array( 'test' => 'isGenericName' );
protected $table = 'test';
protected $identifier = 'id_test';
public function getFields()
{
parent::validateFields();
$fields[ 'test' ] = pSQL( $this->test );
return $fields;
}
}
?>
|
- Crear un archivo en blanco llamado
AdminTest.php
en/admin/tabs
de PrestaShop. - Agregar las siguientes líneas a este archivo:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?php
include_once( PS_ADMIN_DIR . '/../classes/AdminTab.php' );
class AdminTest extends AdminTab
{
public function __construct()
{
$this->table = 'test';
$this->className = 'Test';
$this->lang = false;
$this->edit = true;
$this->delete = true;
$this->fieldsDisplay = array(
'id_test' => array(
'title' => $this->l( 'ID' ),
'align' => 'center',
'width' => 25 ),
'test' => array(
'title' => $this->l( 'Name' ),
'width' => 200 )
);
$this->identifier = 'id_test';
parent::__construct();
}
public function displayForm()
{
global $currentIndex;
$defaultLanguage = intval( Configuration::get( 'PS_LANG_DEFAULT' ) );
$languages = Language::getLanguages();
$obj = $this->loadObject( true );
echo '
<script type="text/javascript">
id_language = Number('.$defaultLanguage.');
</script>';
echo '
<form action="' . $currentIndex . '&submitAdd' . $this->table . '=1&token=' . $this->token . '" method="post" class="width3">
' . ($obj->id ? '<input type="hidden" name="id_' . $this->table . '" value="' . $obj->id . '" />' : '').'
<fieldset><legend><img src="../img/admin/profiles.png" />' . $this->l( 'Profiles' ) . '</legend>
<label>'.$this->l( 'Name:' ).' </label>
<div class="margin-form">';
foreach ( $languages as $language )
echo '
<div id="name_' . $language['id_lang'|'id_lang'] . '" style="display: ' . ($language['id_lang'|'id_lang'] == $defaultLanguage ? 'block' : 'none') . '; float: left;">
<input size="33" type="text" name="name_' . $language['id_lang'|'id_lang'] . '" value="' . htmlentities( $this->getFieldValue( $obj, 'name', intval( $language['id_lang'|'id_lang'] ) ), ENT_COMPAT, 'UTF-8' ) . '" /><sup>*</sup>
</div>';
$this->displayFlags( $languages, $defaultLanguage, 'name', 'name' );
echo '
<div class="clear"></div>
</div>
<div class="margin-form">
<input type="submit" value="' . $this->l( ' Save ' ) . '" name="submitAdd' . $this->table . '" class="button" />
</div>
<div class="small"><sup>*</sup> ' . $this->l( 'Required field' ) . '</div>
</fieldset>
</form> ';
}
}
?>
|
...
He aquí un resumen de la arquitectura del módulo de PrestaShop:
Cuando una de las páginas del sitio es cargada, el motor de PrestaShop revisa los módulos que deben ser invocados para a cada uno de los hooks que conforman la página.
...
Nombre del Hook | Ubicación del Archivo | Visible | Descripción |
---|---|---|---|
header | header.php | No | Llamado entre las etiquetasHEAD. Ubicación ideal para agregar archivos JavaScript y CSS. |
top | header.php | Sí | Llamado en el encabezado de la página. |
leftColumn | header.php | Sí | Llamado al cargar la columna izquierda. |
rightColumn | footer.php | Sí | Llamado cuando se carga la columna derecha. |
footer | footer.php | Sí | Llamado en el pie de la página. |
home | index.php | Sí | Llamado en el centro de la página de inicio. |
...
Ficha de Producto
Nombre del Hook | Ubicación del Archivo | Visible | Descripción |
---|---|---|---|
extraLeft | product.php | Sí | Llamado justo antes del enlace "Imprimir", debajo de la foto. |
extraRight | product.php | Sí | Llamado justo después del bloque del botón "Añadir al carrito". |
productActions | product.php | Sí | Llamado dentro del bloque del botón "Añadir al carrito", después de ese botón. |
productOutOfStock | product.php | Sí | Llamado dentro del bloque del botón "Añadir al carrito", después de la información de "disponibilidad". |
productfooter | product.php | Sí | Llamado antes de las pestañas. |
productTab | product.php | Sí | Llamado en la lista de pestañas, como "Más información", "Hoja de datos", "Accesorios"... Ubicación ideal para una pestaña extra, cuyo contenido es manejado por el hook |
productTabContent | product.php | Sí | Llamado cuando se hace clic en una pestaña. Ubicación ideal para el contenido de una pestaña extra, que ha sido definida utilizando el hook |
...
Nombre del Hook | Ubicación del Archivo | Visible | Descripción |
---|---|---|---|
payment | order.php | Sí | Llamado cuando necesita construir una lista de soluciones de pago disponibles, durante el proceso del pedido. Ubicación ideal para permitir la elección de un módulo de pago que usted ha desarrollado. |
paymentReturn | order-confirmation.php | Sí | Llamado cuando el usuario es regresado a la tienda después de haber pagado en una página externa. Ubicación ideal para mostrar una confirmación u ofrecer detalles sobre el pago. |
orderConfirmation | order-confirmation.php | Sí | Un duplicado de |
backBeforePayment | order.php | No | Llamado al mostrar la lista de soluciones de pago disponibles. Ubicación ideal para redirigir al usuario en lugar de mostrar dicha lista (p.ej., finalización de 1-clic de PayPal).. |
Devoluciones de Mercancías
...
Nombre del Hook | Ubicación del Archivo | Visible | Descripción |
---|---|---|---|
newOrder | Class: PaymentModule.php | No | Llamado durante el proceso de creación de un nuevo pedido, después de que ha sido creado. |
paymentConfirm | Class: Hook.php | No | Llamado cuando el estado de un pedido se convierte en "pago aceptado". |
updateOrderStatus | Class: OrderHistory.php | No | Llamado cuando el estado de un pedido se cambia, antes de ser cambiado. |
postUpdateOrderStatus | Class: OrderHistory.php | No | Llamado cuando el estado de un pedido se cambia, después de ser cambiado. |
cancelProduct | AdminOrders.php | No | Llamado cuando un elemento es eliminado de un pedido, después de la eliminación. |
invoice | AdminOrders.php | Sí | Llamado cuando los detalles de un pedido son mostrados, encima del bloque de Información del Cliente. |
adminOrder | AdminOrders.php | Sí | Llamado cuando los detalles de un pedido son mostrados, debajo del bloque de Información del Cliente. |
orderSlip | AdminOrders.php | No | Llamado durante la creación de una nota de crédito, después de que ha sido creada. |
Productos
...
Nombre del Hook | Ubicación del Archivo | Visible | Descripción |
---|---|---|---|
adminCustomers | AdminCustomers.php | Sí | Llamado cuando los detalles de un cliente son los mostrados, después de la lista de grupos a la que el cliente actual pertenece. |
...
Si resulta que su problema se debe a un error de PrestaShop en lugar de su código, envíe el problema al “bug-tracker” de PrestaShop: http://forge.prestashop.com/ (es necesario registrarse). Esto le permite discutir el problema directamente con los desarrolladores de PrestaShop.
...