Skip to content

Architecture

This page documents the internal structure of the OCMLabs_SupportTicket module for developers extending or integrating with it.

  • 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

One row per support ticket.

ColumnTypeNotes
ticket_idint, PK, auto-increment
customer_idintFK customer_entity.entity_id, CASCADE delete
product_idint, nullableFK catalog_product_entity.entity_id, SET NULL on delete
order_idint, nullableFK sales_order.entity_id, SET NULL on delete
subjectvarchar(255)Ticket title
statusvarchar(32), default openopen / pending / in_progress / resolved
priorityvarchar(32), default mediumlow / medium / high / urgent
categoryvarchar(64), nullablebilling / shipping / product_issue / general / other
store_idsmallint, nullableFK store.store_id, SET NULL on delete
created_attimestampSet on insert
updated_attimestampAuto-updated on every save

Indexes: customer_id, product_id, status, store_id.

One row per message in a ticket thread. The initial customer message and all subsequent replies are stored here.

ColumnTypeNotes
comment_idint, PK, auto-increment
ticket_idintFK ocmlabs_support_ticket.ticket_id, CASCADE delete
author_typevarchar(32)customer or admin
author_idintCustomer entity ID or admin user ID
messagetextFull message body
is_editedsmallint(1), default 0Edit flag (reserved for future use)
created_attimestampSet on insert
updated_attimestampAuto-updated on every save

Index: ticket_id.

  • TicketRepositoryInterface / TicketRepository - Full CRUD for tickets. Implements save(), getById(), delete(), deleteById(), and getList() with SearchCriteriaInterface. Used by all controllers and the admin data provider.
  • CommentRepositoryInterface / CommentRepository - Full CRUD for comments. Comments are loaded by ticket_id when rendering a ticket thread.

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.

ClassValues
Source\Statusopen, pending, in_progress, resolved
Source\Prioritylow, medium, high, urgent
Source\Categorybilling, 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.

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 from customer_id.
  • Ui\Component\Listing\Column\ProductName - Loads the product and returns its name from product_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).

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\Comments block, 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 the Ticket\AddComment controller.
ControllerAction
IndexRenders the ticket listing page
EditLoads a ticket by ID and renders the edit form
NewActionRenders an empty edit form for admin-created tickets
SavePersists ticket field changes (subject, status, priority, category)
DeleteDeletes a single ticket by ID
MassDeleteDeletes multiple tickets from grid selection
MassStatusUpdates status on multiple tickets from grid selection
AddCommentSaves an admin comment and changes status to in_progress; triggers the customer notification email
ControllerAction
IndexCustomer’s ticket list (requires login; scoped to customer_id)
CreateRenders the ticket creation form with available products (via PurchaseValidator)
CreatePostValidates and saves a new ticket + initial comment; triggers the new-ticket notifications
ViewLoads a ticket and its full comment thread (ownership-checked against the session customer)
AddCommentSaves a customer reply; changes status (in_progress to pending, resolved to open); triggers the admin notification
ResolveSets ticket status to resolved; triggers the resolved notification to the customer
AjaxCreateAjax endpoint used by the product-page Support button; creates a ticket without a full page navigation
BlockTemplatePurpose
Block\Customer\TicketCreatecustomer/ticket-create.phtmlRenders the create form with the customer’s list of purchased products (filtered by PurchaseValidator) and the category/priority option arrays.
Block\Customer\TicketListcustomer/ticket-list.phtmlLoads and paginates the customer’s tickets.
Block\Customer\TicketViewcustomer/ticket-view.phtmlLoads a single ticket with its full comment thread. Handles ownership validation.
Block\Product\SupportButtonproduct/support-button.phtmlRenders the Support button on product pages. Posts to AjaxCreate when the customer is logged in; redirects to the create form otherwise.
  • Admin router (etc/adminhtml/routes.xml): frontend name ocmlabs_support, area adminhtml.
  • Frontend router (etc/frontend/routes.xml): frontend name ocmlabs_support, area frontend. All frontend ticket routes require a logged-in customer session. Requests for another customer’s ticket return a 404.

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.

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.

All paths are rooted at ocmlabs_support_ticket/* and rendered under Stores > Configuration > OrangeCollar > Support Tickets.

PathTypeDefault
general/enabledselect (Yes/No)1
general/admin_emailtext(empty)
general/email_senderselectgeneral
email_templates/new_customer_templateselectdefault
email_templates/new_admin_templateselectdefault
email_templates/comment_customer_templateselectdefault
email_templates/comment_admin_templateselectdefault
email_templates/resolved_templateselectdefault