Architecture
This page documents the internal structure of the OCMLabs_SupportTicket module for developers extending or integrating with it.
Module identity
Section titled “Module identity”- Module name:
OCMLabs_SupportTicket - Composer package:
ocmlabs/module-support-ticket - Commerce metapackage:
ocmlabs/module-support-ticket-commerce - PHP requirement:
^8.3 - Magento dependencies:
Magento_Catalog,Magento_Customer,Magento_Email,Magento_Sales,Magento_Store
Database schema
Section titled “Database schema”ocmlabs_support_ticket
Section titled “ocmlabs_support_ticket”One row per support ticket.
| Column | Type | Notes |
|---|---|---|
ticket_id | int, PK, auto-increment | |
customer_id | int | FK customer_entity.entity_id, CASCADE delete |
product_id | int, nullable | FK catalog_product_entity.entity_id, SET NULL on delete |
order_id | int, nullable | FK sales_order.entity_id, SET NULL on delete |
subject | varchar(255) | Ticket title |
status | varchar(32), default open | open / pending / in_progress / resolved |
priority | varchar(32), default medium | low / medium / high / urgent |
category | varchar(64), nullable | billing / shipping / product_issue / general / other |
store_id | smallint, nullable | FK store.store_id, SET NULL on delete |
created_at | timestamp | Set on insert |
updated_at | timestamp | Auto-updated on every save |
Indexes: customer_id, product_id, status, store_id.
ocmlabs_support_ticket_comment
Section titled “ocmlabs_support_ticket_comment”One row per message in a ticket thread. The initial customer message and all subsequent replies are stored here.
| Column | Type | Notes |
|---|---|---|
comment_id | int, PK, auto-increment | |
ticket_id | int | FK ocmlabs_support_ticket.ticket_id, CASCADE delete |
author_type | varchar(32) | customer or admin |
author_id | int | Customer entity ID or admin user ID |
message | text | Full message body |
is_edited | smallint(1), default 0 | Edit flag (reserved for future use) |
created_at | timestamp | Set on insert |
updated_at | timestamp | Auto-updated on every save |
Index: ticket_id.
Service layer
Section titled “Service layer”Repositories
Section titled “Repositories”TicketRepositoryInterface/TicketRepository- Full CRUD for tickets. Implementssave(),getById(),delete(),deleteById(), andgetList()withSearchCriteriaInterface. Used by all controllers and the admin data provider.CommentRepositoryInterface/CommentRepository- Full CRUD for comments. Comments are loaded byticket_idwhen rendering a ticket thread.
Services
Section titled “Services”NotificationService
Handles all outgoing email. Called from the customer and admin comment controllers and the ticket creation controller. Sends five distinct notification types:
- New ticket - customer confirmation
- New ticket - admin alert
- New comment - customer notification (admin replied)
- New comment - admin notification (customer replied)
- Ticket resolved - customer confirmation
PurchaseValidator
Queries the sales order tables to confirm a given customer has purchased a given product. Used to populate the product dropdown on the ticket creation form with only verified purchases, and to reject server-side any attempt to submit a ticket against a product the customer does not own.
Source models
Section titled “Source models”| Class | Values |
|---|---|
Source\Status | open, pending, in_progress, resolved |
Source\Priority | low, medium, high, urgent |
Source\Category | billing, shipping, product_issue, general, other |
Each source model is used by the listing grid filter, the edit form select, and (for Status) the MassStatus bulk action.
Admin UI components
Section titled “Admin UI components”Listing (ocmlabs_support_ticket_listing.xml)
Section titled “Listing (ocmlabs_support_ticket_listing.xml)”Standard Magento UI component listing. The DataSource maps to the ticket collection via TicketRepository. Custom column components resolve foreign-key IDs to human-readable values at render time:
Ui\Component\Listing\Column\CustomerName- Loads the customer entity and returns the full name fromcustomer_id.Ui\Component\Listing\Column\ProductName- Loads the product and returns its name fromproduct_id.Ui\Component\Listing\Column\TicketActions- Renders the View action link per row.
Mass actions: Set Status (submits to the MassStatus controller with the chosen status value) and Delete (submits to the MassDelete controller with confirmation).
Form (ocmlabs_support_ticket_form.xml)
Section titled “Form (ocmlabs_support_ticket_form.xml)”Edit form with two fieldsets. The DataProvider is TicketFormDataProvider, which extends the standard form data provider and enriches the raw row with resolved customer_name and product_name values before handing it to the form.
- Ticket Details fieldset -
subject(editable),status(select),priority(select),category(select),customer_name(link component),product_name(disabled),created_at(disabled),updated_at(disabled). - Comments fieldset - Renders the
Block\Adminhtml\Ticket\Edit\Commentsblock, which loads all comments for the ticket and outputs the conversation thread as HTML. The Add Reply textarea and submit are part of this block, posting to theTicket\AddCommentcontroller.
Controllers
Section titled “Controllers”Admin (Controller/Adminhtml/Ticket/)
Section titled “Admin (Controller/Adminhtml/Ticket/)”| Controller | Action |
|---|---|
Index | Renders the ticket listing page |
Edit | Loads a ticket by ID and renders the edit form |
NewAction | Renders an empty edit form for admin-created tickets |
Save | Persists ticket field changes (subject, status, priority, category) |
Delete | Deletes a single ticket by ID |
MassDelete | Deletes multiple tickets from grid selection |
MassStatus | Updates status on multiple tickets from grid selection |
AddComment | Saves an admin comment and changes status to in_progress; triggers the customer notification email |
Frontend (Controller/Ticket/)
Section titled “Frontend (Controller/Ticket/)”| Controller | Action |
|---|---|
Index | Customer’s ticket list (requires login; scoped to customer_id) |
Create | Renders the ticket creation form with available products (via PurchaseValidator) |
CreatePost | Validates and saves a new ticket + initial comment; triggers the new-ticket notifications |
View | Loads a ticket and its full comment thread (ownership-checked against the session customer) |
AddComment | Saves a customer reply; changes status (in_progress to pending, resolved to open); triggers the admin notification |
Resolve | Sets ticket status to resolved; triggers the resolved notification to the customer |
AjaxCreate | Ajax endpoint used by the product-page Support button; creates a ticket without a full page navigation |
Frontend blocks and templates
Section titled “Frontend blocks and templates”| Block | Template | Purpose |
|---|---|---|
Block\Customer\TicketCreate | customer/ticket-create.phtml | Renders the create form with the customer’s list of purchased products (filtered by PurchaseValidator) and the category/priority option arrays. |
Block\Customer\TicketList | customer/ticket-list.phtml | Loads and paginates the customer’s tickets. |
Block\Customer\TicketView | customer/ticket-view.phtml | Loads a single ticket with its full comment thread. Handles ownership validation. |
Block\Product\SupportButton | product/support-button.phtml | Renders the Support button on product pages. Posts to AjaxCreate when the customer is logged in; redirects to the create form otherwise. |
Routing
Section titled “Routing”- Admin router (
etc/adminhtml/routes.xml): frontend nameocmlabs_support, areaadminhtml. - Frontend router (
etc/frontend/routes.xml): frontend nameocmlabs_support, areafrontend. All frontend ticket routes require a logged-in customer session. Requests for another customer’s ticket return a 404.
Email templates
Section titled “Email templates”Five templates are registered in etc/email_templates.xml. Default template files live in view/frontend/email/. All templates receive the same variable set:
ticket_id, ticket_subject, ticket_status, ticket_priority,customer_name, customer_email, product_name, comment_message,view_url, account_url, admin_urlTemplates are configurable per store view under Stores > Configuration > OrangeCollar > Support Tickets > Email Templates. See Email Notifications for the customization procedure.
ACL resources
Section titled “ACL resources”Magento_Backend::admin└── OCMLabs_SupportTicket::support ├── OCMLabs_SupportTicket::tickets - View ticket grid │ ├── OCMLabs_SupportTicket::tickets_manage - Edit tickets and add replies │ └── OCMLabs_SupportTicket::tickets_delete - Delete tickets └── OCMLabs_SupportTicket::config - Access module configurationThe admin menu item under Stores > Support requires OCMLabs_SupportTicket::tickets. The configuration link requires OCMLabs_SupportTicket::config.
System configuration paths
Section titled “System configuration paths”All paths are rooted at ocmlabs_support_ticket/* and rendered under Stores > Configuration > OrangeCollar > Support Tickets.
| Path | Type | Default |
|---|---|---|
general/enabled | select (Yes/No) | 1 |
general/admin_email | text | (empty) |
general/email_sender | select | general |
email_templates/new_customer_template | select | default |
email_templates/new_admin_template | select | default |
email_templates/comment_customer_template | select | default |
email_templates/comment_admin_template | select | default |
email_templates/resolved_template | select | default |