📧 Email personalizado con template — patron completo

Actualizado: 2025-01-15

#Estructura de templates de email

Arbol de archivos para emails en un modulo
text
modules/ecom_notifications/
├── mails/
│   ├── es/
│   │   ├── order_shipped.html    # Template HTML
│   │   └── order_shipped.txt     # Template texto plano (obligatorio)
│   ├── en/
│   │   ├── order_shipped.html
│   │   └── order_shipped.txt
│   └── fr/
│       ├── order_shipped.html
│       └── order_shipped.txt
└── ecom_notifications.php
⚠️
Siempre crea ambas versiones

PrestaShop requiere tanto el .html como el .txt. Si falta el .txt, Mail::Send() fallara silenciosamente en algunas configuraciones.

#Template HTML del email

mails/es/order_shipped.html
html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Tu pedido ha sido enviado</title>
</head>
<body style="margin:0; padding:0; background:#f4f4f4; font-family:Arial,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f4f4f4;">
  <tr>
    <td align="center" style="padding:20px 0;">
      <table width="600" cellpadding="0" cellspacing="0" style="background:#ffffff; border-radius:8px; overflow:hidden;">
        <!-- Header -->
        <tr>
          <td style="background:#2fb5d2; padding:30px; text-align:center;">
            <img src="{shop_logo}" alt="{shop_name}" style="max-width:200px;">
          </td>
        </tr>
        <!-- Body -->
        <tr>
          <td style="padding:30px;">
            <h1 style="color:#333; margin:0 0 20px;">Hola {firstname},</h1>
            <p style="color:#555; font-size:16px; line-height:1.6;">
              Tu pedido <strong>#{order_reference}</strong> ha sido enviado.
            </p>
            <table width="100%" style="background:#f8f9fa; border-radius:6px; padding:15px; margin:20px 0;">
              <tr>
                <td style="padding:8px;"><strong>Transportista:</strong></td>
                <td style="padding:8px;">{carrier_name}</td>
              </tr>
              <tr>
                <td style="padding:8px;"><strong>N. seguimiento:</strong></td>
                <td style="padding:8px;"><a href="{tracking_url}">{tracking_number}</a></td>
              </tr>
              <tr>
                <td style="padding:8px;"><strong>Fecha envio:</strong></td>
                <td style="padding:8px;">{shipping_date}</td>
              </tr>
            </table>
            <p style="color:#555; font-size:14px;">
              Recibiras tu pedido en {delivery_days} dias laborables.
            </p>
            <p style="text-align:center; margin:30px 0;">
              <a href="{tracking_url}" style="background:#2fb5d2; color:#fff; padding:12px 30px; border-radius:6px; text-decoration:none; font-weight:bold;">Seguir mi pedido</a>
            </p>
          </td>
        </tr>
        <!-- Footer -->
        <tr>
          <td style="background:#f8f9fa; padding:20px; text-align:center; font-size:12px; color:#999;">
            <p>{shop_name} — {shop_url}</p>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>
</body>
</html>

#Template TXT del email

mails/es/order_shipped.txt
text
Hola {firstname},

Tu pedido #{order_reference} ha sido enviado.

Transportista: {carrier_name}
N. seguimiento: {tracking_number}
Fecha de envio: {shipping_date}

Seguir mi pedido: {tracking_url}

Recibiras tu pedido en {delivery_days} dias laborables.

{shop_name} — {shop_url}

#Enviar el email desde PHP

Mail::Send() con todas las opciones
php
<?php
/**
 * Enviar email de envio al cliente
 */
public function sendShippingEmail(Order $order, OrderCarrier $orderCarrier): bool
{
    $customer = new Customer($order->id_customer);
    $carrier  = new Carrier($orderCarrier->id_carrier, $customer->id_lang);

    // Variables que se reemplazan en el template ({variable})
    $templateVars = [
        '{firstname}'        => $customer->firstname,
        '{lastname}'         => $customer->lastname,
        '{order_reference}'  => $order->reference,
        '{carrier_name}'     => $carrier->name,
        '{tracking_number}'  => $orderCarrier->tracking_number,
        '{tracking_url}'     => str_replace('@', $orderCarrier->tracking_number, $carrier->url),
        '{shipping_date}'    => Tools::displayDate(date('Y-m-d'), null, true),
        '{delivery_days}'    => $carrier->delay[$customer->id_lang] ?? '3-5',
    ];

    return Mail::Send(
        (int) $customer->id_lang,       // Idioma del cliente
        'order_shipped',                 // Nombre del template (sin extension)
        'Tu pedido ha sido enviado',     // Asunto del email
        $templateVars,                   // Variables del template
        $customer->email,                // Email destinatario
        $customer->firstname . ' ' . $customer->lastname,  // Nombre destinatario
        null,                            // Email remitente (null = config tienda)
        null,                            // Nombre remitente (null = config tienda)
        null,                            // Adjuntos (array de paths)
        null,                            // Modo (null = normal)
        _PS_MODULE_DIR_ . $this->name . '/mails/', // Directorio de templates
        false,                           // No morir en error
        (int) $order->id_shop            // Shop ID
    );
}

#Email con adjunto

Enviar email con PDF adjunto
php
<?php
// Generar PDF de factura
$pdf = new PDF($order->getInvoicesCollection(), PDF::TEMPLATE_INVOICE, $this->context->smarty);
$pdfContent = $pdf->render(false); // false = devolver string, no enviar al navegador

// Guardar PDF temporal
$tmpFile = _PS_TMP_DIR_ . 'invoice_' . $order->reference . '.pdf';
file_put_contents($tmpFile, $pdfContent);

// Adjuntos: array de arrays con 3 claves
$attachments = [
    [
        'content' => $pdfContent,          // Contenido binario del archivo
        'name'    => 'factura-' . $order->reference . '.pdf',  // Nombre del archivo
        'mime'    => 'application/pdf',     // Tipo MIME
    ],
];

Mail::Send(
    (int) $customer->id_lang,
    'order_invoice',
    'Tu factura ' . $order->reference,
    $templateVars,
    $customer->email,
    $customer->firstname,
    null, null,
    $attachments,         // <-- Adjuntos aqui
    null,
    _PS_MODULE_DIR_ . $this->name . '/mails/'
);

// Limpiar temporal
@unlink($tmpFile);

#Hook para modificar emails del sistema

actionEmailSendBefore — interceptar y modificar cualquier email
php
<?php
/**
 * Este hook se ejecuta ANTES de enviar cualquier email del sistema.
 * Puedes modificar asunto, variables, destinatarios, o cancelar el envio.
 */
public function hookActionEmailSendBefore($params)
{
    // $params contiene:
    // 'idLang', 'template', 'subject', 'templateVars',
    // 'to', 'toName', 'from', 'fromName', 'fileAttachment',
    // 'mode_smtp', 'templatePath', 'die', 'idShop'

    $template = $params['template'];

    // Ejemplo 1: Anadir variables custom a TODOS los emails
    $params['templateVars']['{custom_footer}'] = 'Powered by Ecom Experts';
    $params['templateVars']['{year}'] = date('Y');

    // Ejemplo 2: Cambiar asunto de emails de pedido
    if ($template === 'order_conf') {
        $params['subject'] = 'Gracias por tu pedido! ' . $params['subject'];
    }

    // Ejemplo 3: BCC — enviar copia a admin de todos los pedidos
    if (in_array($template, ['order_conf', 'payment', 'shipped'])) {
        // Nota: PS no soporta BCC nativo, pero puedes enviar otra copia
        Mail::Send(
            (int) $params['idLang'],
            $template,
            '[COPIA] ' . $params['subject'],
            $params['templateVars'],
            Configuration::get('PS_SHOP_EMAIL'),
            Configuration::get('PS_SHOP_NAME')
        );
    }

    // Ejemplo 4: Cancelar envio de email (devolver false)
    // if ($template === 'newsletter_conf') {
    //     return false; // El email NO se envia
    // }

    return $params; // Devolver params modificados
}
Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.