-
Notifications
You must be signed in to change notification settings - Fork 15
Portal Request Catalogue
Where: the self-service portal β Request Something Publish with: Forms β the π globe icon on a form's row Starts empty on purpose β no form is offered to customers until you say so
Customers pick what they need from a list of forms β a new starter, a laptop, an access request β fill it in, and submit. The answers arrive in Forms β Submissions for your team to action.
Nothing appears in the catalogue until you publish it. In Forms, each row has a globe action:
- Outline globe β internal only. This is the default for every form, old and new.
- Filled globe + "In catalogue" pill β customers can request it.
π‘ Why this isn't just the Active switch. Active is your own on/off β whether the form can be used at all. Being in the catalogue is a different decision: your New Starter Request is active and used daily by managers, but has no business appearing on every customer's menu. They're separate switches because they answer separate questions.
Editing a published form keeps it published. (Editing creates a new version behind the scenes, and it would be a nasty surprise if pressing Save quietly withdrew your form from customers.)
Only forms that are in the catalogue, active, and the current version. Everything else is invisible β and a form that isn't offered can't be reached even if someone knows its web address, so there's no "hidden but guessable" state.
The form itself shows only its title, description and questions. Who wrote it, how many times it's been revised, and every other piece of internal bookkeeping stays on your side.
The answers are recorded as a submission against that form, exactly like one of your own staff filling it in. In Forms β Submissions you'll see:
- Every answer
- Who submitted it β including customers coming from the portal, marked as such
- When
By default a submission does not automatically become a ticket. You decide which requests need work, rather than having every enquiry open a ticket.
β οΈ Keep an eye on Forms β Submissions β an ordinary catalogue request won't appear in your ticket inbox on its own.
Unless you require approval. A catalogue item can be set to need sign-off first β see Catalogue Request Approvals. When it's approved, the ticket is raised automatically (and the requester sees the status on their own dashboard).
Every question type is a plain input:
| Type | Notes |
|---|---|
| Text, Textarea | Free text |
| Checked as a real address | |
| Number | Checked as numeric |
| Dropdown, Radio | One of the options you configured β and only one of them |
| Checkbox | A single yes/no |
| Checkboxes | Any of the options you configured |
There is no field type that reaches into your system β no picker of assets, tickets or configuration items β so nothing on a form can expose your internal records. There's also no file upload on forms; if you need one, point the customer at raising a ticket, which does support attachments.
Required fields, email format and number format are enforced on the server, not just in the browser. So are the options: an answer to a dropdown must be one of that dropdown's own choices. (That last check was added with this feature β before it, a submitted value was stored as-is, so a "Department" offering four choices could be saved with a fifth.)
You have three forms:
| Form | Active | In catalogue |
|---|---|---|
| New Starter Request | β | β |
| Equipment Return | β | β |
| Old Equipment Return (v1) | β | β (an older version) |
Sarah opens Request Something and sees one entry: New Starter Request.
- Equipment Return isn't in the catalogue.
- Old Equipment Return (v1) is in the catalogue but is a previous version, so it's not offered β only the current one ever is.
She fills it in, choosing IT Support from the Department dropdown, and submits. In Forms β Submissions the request appears attributed to Sarah, flagged as coming from the portal. An analyst reads it and raises a ticket for the work.
Had she tampered with the page to submit "Board of Directors" β not one of the configured options β the server would have refused it.
- The catalogue is the same for every company. Forms is not yet a multi-company module (no company column on any forms table), so on an MSP install every client sees the same list. If you need per-client catalogues, that's the Forms multi-company work.
- No file uploads on forms (as above).
- Approvals are a single designated approver, per item. A catalogue item can require sign-off before a ticket is raised β see Catalogue Request Approvals. Routing to the requester's manager, or a multi-approver board, isn't built yet; for richer routing the Workflows module is still the place.
| π¨ | File | Purpose |
|---|---|---|
| π₯οΈ | self-service/catalogue.php |
The portal page β list, form renderer, submit |
| π | api/self-service/get_catalogue.php |
The offered forms (visible + active + current version) |
| π | api/self-service/get_catalogue_form.php |
One form and its fields, minus all analyst bookkeeping |
| π | api/self-service/submit_catalogue_form.php |
The submit adapter β passes the requester as a separate argument |
| βοΈ | includes/services/forms.php |
FormsService::submitForm() β validation, the visibility re-check, both INSERTs |
| π₯οΈ | forms/index.php |
The globe toggle and the "In catalogue" pill |
| π | api/forms/get_forms.php |
Returns is_portal_visible for the list |
| π | api/forms/get_submissions.php |
Resolves both submitter kinds (analyst and requester) |
| ποΈ | forms.is_portal_visible |
The switch. Defaults to 0 |
| ποΈ | form_submissions.submitted_by_user_id |
The requester who submitted it |
| ποΈ | form_submissions.ticket_id |
The ticket raised from it β NULL until actioned; written when an approval is approved (see Catalogue Request Approvals) |
Two details that matter if you're reading the code:
- The visibility check lives in the service, not only the endpoint. Submitting to an unpublished form is refused even though the adapter never looked β so a future caller can't accidentally bypass it.
-
The requester is stored in its own column.
form_submissions.submitted_byis an analyst id with no foreign key, and every reader joins it to the analysts table β so writing a requester's id there would have silently credited the request to whichever analyst happened to share that number. Exactly one of the two columns is ever set.
- Catalogue Request Approvals β requiring sign-off before a request becomes a ticket
- Forms β building forms, field types, submissions
- Self-Service Portal β the portal itself
- Self-Service Developer Guide β the rules when extending it
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- Theming & Dark Mode
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
- MobileβFriendly
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- Problem Management
- Tasks
- Assets
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
- Forms
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)