Skip to content

Customer Mail History

Flow ID: AD-41 | Module(s): eshop | Complexity: Low Last Updated: 2026-04-04

Business Context

The customer mail history system records every email sent to customers by the platform (order confirmations, shipping notifications, promotional emails, etc.). It provides a stored copy of each email's HTML body so administrators can view exactly what the customer received. A storefront-facing controller allows rendering a single email by ID, typically used for "view in browser" links embedded in outgoing emails.

The model is write-heavy: various parts of the system call addRecord() when sending emails, but there is no admin search/list interface in the core platform -- email history is viewed per-customer on their admin detail page.


API Reference

REST Endpoints

No REST API for mail history.

Legacy Storefront Routes

RouteControllerMethodHTTPDescription
mail_history/view/{id}Adv_customer_mail_historyviewGETRender the stored email HTML body

Note: This extends Front_c (storefront controller), not Admin_c. The email body is echoed directly as raw HTML without any template wrapping.


Code Flow

Recording an Email

  1. Any part of the system that sends customer email calls customer_message_history_model::addRecord().
  2. Parameters: customerId, purpose (type category), messageType (email/sms), subject, message (full HTML body).
  3. Inserts a row into shop_customer_message_history with the current datetime.

Viewing an Email

  1. A "view in browser" link in an email points to mail_history/view/{id}.
  2. Adv_customer_mail_history::view($id) calls customer_message_history_model::getCustomerEmail($id).
  3. The model selects only email_body AS email from the table.
  4. The controller echoes the raw HTML content directly (no layout wrapping).

Viewing Customer History (Admin)

  1. On the customer admin detail page, the customer management controller calls customer_message_history_model::getCustomerEmails($customerId).
  2. Returns all emails for that customer, ordered by insert order.
  3. Displayed in a table showing date, type, subject, with a link to view the full body.

Cleanup Job

  1. The ClearOldEmails scheduled job calls customer_message_history_model::deleteEmailBeforeDate($date).
  2. This removes all records older than the specified date to prevent table bloat.
  3. Configured in application/config/jobs.php with a default schedule of 30 0 * * * (daily at 00:30).

Domain Layer

No modern domain layer. Mail history is managed entirely through the legacy model.


Architecture

ComponentPathPurpose
Adv_customer_mail_historyecommercen/eshop/controllers/Adv_customer_mail_history.phpStorefront controller (23 lines)
Customer_mail_historyapplication/modules/eshop/controllers/Customer_mail_history.phpApp-level wrapper
Adv_customer_message_history_modelecommercen/eshop/models/Adv_customer_message_history_model.phpModel with record/retrieval/cleanup (42 lines)
Customer_message_history_modelapplication/modules/eshop/models/Customer_message_history_model.phpApp-level wrapper
Routesapplication/config/routes.php:605mail_history/(.+) -> eshop/customer_mail_history/$1

Data Model

shop_customer_message_history

ColumnTypeDescription
idint (PK)Auto-increment primary key
user_idint (FK)Customer ID
datetimedatetimeWhen the email was sent
typevarcharPurpose/category of the email (e.g., order_confirmation, shipping_notification)
message_typevarcharDelivery channel: email or sms
subjectvarcharEmail subject line
email_bodylongtextFull HTML body of the email

Configuration

SourceKeyDescription
Job configapplication/config/jobs.php ClearOldEmailsSchedule for purging old email records
Job optionsPer-client options.daysNumber of days to retain (client-configurable)

Client Extension Points

  • Override model: Extend Customer_message_history_model in application/modules/eshop/models/ to add custom record fields or retrieval methods.
  • Override controller: Extend Customer_mail_history in application/modules/eshop/controllers/ to add authentication or custom rendering.
  • Custom cleanup: Override the ClearOldEmails job command or configure options.days in application/config/jobs.php.

Business Rules

  1. No authentication on view: The view() endpoint extends Front_c and does not check if the requester is the email's recipient. Security relies on the URL being hard to guess (numeric ID).
  2. Raw HTML output: The email body is echoed directly without sanitization -- it contains the exact HTML that was sent.
  3. Automatic cleanup: The ClearOldEmails job removes old records to prevent table bloat.
  4. Multi-channel: The message_type field supports both email and sms, though SMS messages typically have no email_body.