Database schema, service layer, controllers, and routing for OCMLabs_SupportTicket
This page documents the internal structure of the OCMLabs_SupportTicket module for developers extending or integrating with it.
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
ocmlabs_support_ticket
One row per support ticket.
| Column | Type | Notes |
|---|---|---|
ticket_ | int, PK, auto-increment | |
customer_ | int | FK customer_, CASCADE delete |
product_ | int, nullable | FK catalog_, SET NULL on delete |
order_ | int, nullable | FK sales_, SET NULL on delete |
subject | varchar(255) | Ticket title |
status | varchar(32), default open | open / pending / in_ / resolved |
priority | varchar(32), default medium | low / medium / high / urgent |
category | varchar(64), nullable | billing / shipping / product_ / general / other |
store_ | smallint, nullable | FK store.store_, SET NULL on delete |
created_ | timestamp | Set on insert |
updated_ | timestamp | Auto-updated on every save |
Indexes: customer_id, product_id, status, store_id.
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_ | int, PK, auto-increment | |
ticket_ | int | FK ocmlabs_, CASCADE delete |
author_ | varchar(32) | customer or admin |
author_ | int | Customer entity ID or admin user ID |
message | text | Full message body |
is_ | smallint(1), default 0 | Edit flag (reserved for future use) |
created_ | timestamp | Set on insert |
updated_ | timestamp | Auto-updated on every save |
Index: ticket_id.
Service layer
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
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
| Class | Values |
|---|---|
Source\ | open, pending, in_, resolved |
Source\ | low, medium, high, urgent |
Source\ | billing, shipping, product_, 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
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)
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
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_; triggers the customer notification email |
Frontend (Controller/Ticket/)
| Controller | Action |
|---|---|
Index | Customer’s ticket list (requires login; scoped to customer_) |
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_ 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
| Block | Template | Purpose |
|---|---|---|
Block\ | customer/ | Renders the create form with the customer’s list of purchased products (filtered by PurchaseValidator) and the category/priority option arrays. |
Block\ | customer/ | Loads and paginates the customer’s tickets. |
Block\ | customer/ | Loads a single ticket with its full comment thread. Handles ownership validation. |
Block\ | product/ | Renders the Support button on product pages. Posts to AjaxCreate when the customer is logged in; redirects to the create form otherwise. |
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
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_url
Templates are configurable per store view under Stores > Configuration > OrangeCollar > Support Tickets > Email Templates. See Email Notifications for the customization procedure.
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 configuration The admin menu item under Stores > Support requires OCMLabs_SupportTicket::tickets. The configuration link requires OCMLabs_SupportTicket::config.
System configuration paths
All paths are rooted at ocmlabs_support_ticket/* and rendered under Stores > Configuration > OrangeCollar > Support Tickets.
| Path | Type | Default |
|---|---|---|
general/ | select (Yes/No) | 1 |
general/ | text | (empty) |
general/ | select | general |
email_ | select | default |
email_ | select | default |
email_ | select | default |
email_ | select | default |
email_ | select | default |