COMMERCIAL PRODUCT EDITION
Build one support brain for every business you operate.
This manual covers fresh installation, upgrades, customer cases, formal PDF quotations, embeddable forms, AI business agents, security, demos and reseller preparation.
Quick Start
Fresh installation
- Create a domain or subdomain document root, for example `support.example.com`.
- Create an **empty** MySQL or MariaDB database and assign a user with all privileges on that database.
- Upload the contents of the full-source ZIP directly into the document root.
- Confirm the root contains `index.php`, `.htaccess`, `app/`, `admin/`, `install/`, `assets/`, `database/` and `storage/`.
- Set these directories writable by PHP, normally `0755`:
- app/ temporarily during installation
- storage/
- storage/attachments/
- storage/logs/
- storage/v2/support/
- storage/v2/quotes/
- assets/uploads/brands/
- assets/uploads/ai-agents/
- assets/uploads/v2-businesses/
- Browse to `https://your-domain.example/install/`.
- Complete the installer and create the master administrator.
- Confirm the customer portal and administrator portal work.
- Delete or rename the `install/` directory. Keep `storage/installed.lock`.
- Configure SMTP, businesses, routing, forms, quotation settings and AI agents.
Key URLs
- Customer portal: `/`
- Open a case: `/new/`
- Get a quote: `/quote/`
- Find a case or quote: `/search/`
- Customer dashboard: `/client/`
- Master administrator: `/admin/master/`
- Routing manager: `/admin/master/routing-v2.php`
- Quotations: `/admin/master/quotes-v2.php`
- AI agents: `/admin/master/ai-agents.php`
- System check: `/admin/master/system-check.php`
First configuration checklist
- Replace the default company name and logo.
- Add or review countries, businesses and services.
- Configure at least one active business SMTP profile.
- Test case confirmation, quotation email and OTP email.
- Review upload limits and PHP `post_max_size`/`upload_max_filesize`.
- Add allowed origins before embedding forms on external sites.
- Keep AI providers disabled until a valid provider key and approved knowledge are configured.
Server Requirements
Supported environment
- PHP **8.1 or newer**. PHP 8.2 and 8.3 are recommended.
- MySQL 8.x or MariaDB 10.4+.
- Apache or LiteSpeed with `.htaccess` support. Nginx can be used with equivalent routing rules.
- HTTPS is strongly recommended and required for production customer authentication and secure cross-site embeds.
Required PHP extensions
- PDO
- PDO MySQL
- JSON
- Session
- Fileinfo
- OpenSSL or Sodium
- mbstring is strongly recommended
Optional extensions and access
- cURL, or `allow_url_fopen`, for external AI providers and optional currency/location services.
- Outbound HTTPS access on port 443 for AI-provider calls and external services.
- SMTP connectivity to the selected SMTP host and port.
Recommended limits
- `memory_limit`: 128 MB minimum; 256 MB recommended.
- `upload_max_filesize`: 10 MB or higher.
- `post_max_size`: larger than `upload_max_filesize`, especially for multi-file forms.
- `max_execution_time`: 60 seconds or higher for installation and large knowledge imports.
- `max_input_vars`: 2000 or higher for complex forms and routing configuration.
Writable paths
The web server must be able to write to configuration only during installation and to operational upload/log directories afterwards. Recommended permissions are 0755; use 0775 only when required by the hosting group configuration. Never set the whole product tree to 0777.
Fresh Installation
Web installer method
The web installer is the recommended method.
- Upload source files to the final domain or subdomain document root.
- Create an empty database and database user.
- Visit `/install/`.
- Review the automated server checks.
- Enter database, URL, branding and administrator details.
- Select an initial profile:
- Generic Starter — one editable business and one support form.
- Emaila Showcase — sanitized multi-country example data.
- Blank Configuration — schema only.
- Complete installation.
- Delete or rename `install/`.
The installer writes private configuration to app/config.local.php, creates storage/installed.lock, imports the database schema and selected seed, and creates the first administrator account.
Manual method
Use this only when the hosting environment cannot run the web installer.
- Import `database/schema.sql` into an empty database.
- Import one optional seed:
- database/seed-starter.sql, or
- database/seed-emaila-showcase.sql.
- Copy `app/config.example.php` to `app/config.local.php`.
- Enter database details, base URL, application key, support email and branding values.
- Generate a password hash:
php -r "echo password_hash('Choose-A-Strong-Password', PASSWORD_DEFAULT), PHP_EOL;"
- Insert the administrator using the generated hash:
INSERT INTO admin_users
(email,full_name,password_hash,is_active,created_at,updated_at)
VALUES
('admin@example.com','Master Administrator','PASTE_HASH_HERE',1,UTC_TIMESTAMP(),UTC_TIMESTAMP());
- Create `storage/installed.lock` with any non-empty text.
- Set writable-directory permissions and open the system check.
Installation profiles are not customer data
All included seed and demo records are fictional and contain no SMTP password, AI API key, database password or real customer record.
Upgrade Guide
Before every upgrade
- Export the complete database.
- Back up the complete product directory.
- Preserve `app/config.local.php`.
- Preserve `storage/attachments/`, `storage/v2/`, and all upload directories.
- Place the portal in maintenance mode when the update changes database structure.
Upgrading from 2.0.1 to 2.1.0
- Overwrite source files with the 2.1.0 update while preserving the private files and upload directories listed above.
- Import `database/updates/v2.0.1-to-v2.1.0.sql` once.
- Clear LiteSpeed, PHP OPcache and browser caches.
- Open `/admin/master/system-check.php`.
- Test administrator login, customer login, case reply, quote PDF and email.
The 2.1.0 SQL update adds or refreshes product metadata only. It does not delete cases, quotes, customers, forms, AI agents or email configuration.
Never use the fresh installer on a live database
The fresh installer requires an empty database. Upgrades must use the matching update package and SQL migration. Importing database/schema.sql into a live installation can fail because tables already exist.
Administrator Guide
Dashboard areas
The administrator portal is available at /admin/master/.
Customer support
- **Dashboard** — headline case, customer and message activity.
- **Cases** — legacy/dynamic-form support tickets.
- **Routed Cases** — V2 country → business → service cases.
- **Website Enquiries** — compatible records captured by earlier Emaila website forms.
- **Customers** — verified customer accounts and activity.
Quotations
- **Quotations** — requests, drafts, sent quotes, revisions, accepted and closed quotes.
- **Quote Settings** — default validity, terms, email language and embed code.
- **PDF Quote** — itemised A4 output generated by PHP.
Business configuration
- **Brands & SMTP** — support identity and business-specific mail delivery.
- **Forms & Embed** — dynamic fields, automatic acknowledgement and external form embed.
- **Routing Manager** — countries, businesses, business-country mapping, services and service-country mapping.
AI business agents
- **AI Agents** — create unlimited agent workspaces.
- **AI Training** — manual Q&A, CSV, JSON and bulk imports.
- **AI Conversations** — review source, latency, feedback and human handoff.
- **AI Provider** — disabled, OpenAI Responses API or OpenAI-compatible endpoint.
- **Read-only Data** — tightly controlled parameterised SELECT lookups.
Operations
- **Email Logs** — delivery success/failure records.
- **System Check** — database, folders, extensions and tables.
Administrator security
- Failed logins are rate-limited and logged by IP hash.
- Passwords use PHP's current `PASSWORD_DEFAULT` hash.
- Forms use CSRF tokens.
- Private notes are never exposed to customers.
- Regenerating embed/widget keys invalidates old external code.
Customer Portal
Customers can use password or email OTP access, depending on email configuration.
Customer actions
- Open a routed support case.
- Submit a structured quotation request.
- Find a record using Case ID or Quote ID and matching email.
- Sign in to see all records associated with the verified email.
- Reply to open cases and quotations.
- Upload approved file types.
- Download permitted attachments and formal quotation PDFs.
- Accept, decline or request revision of a quotation.
- Refresh conversations for the latest reply.
Identity and record matching
The portal treats normalized email address as the primary customer identity. When a customer verifies or signs in, existing cases using the same email are associated with the customer account where safe to do so.
Email OTP requirements
OTP delivery requires a working SMTP profile. Codes expire, have retry limits, and are stored as hashes rather than plaintext.
Cases, Routing and Forms
Guided support flow
The V2 support flow presents one stage at a time:
- Country
- Available business in that country
- Available service for that business and country
- Customer details, subject, requirements, attachments and CAPTCHA
The Routing Manager controls every option without source-code changes.
Dynamic support forms
Each support brand can have one or more forms. Fields support text, email, phone, textarea, select, multiselect, checkbox and other configured types. Administrators can control:
- required/optional state
- field width and order
- help text and placeholders
- option lists
- validation rules
- CAPTCHA
- attachments and limits
- success message
- automatic acknowledgement
- allowed embed origins
Case workflow
Typical legacy/dynamic case states are open, waiting_admin, waiting_customer, resolved, closed and spam. Routed V2 cases support open, in_progress, waiting_customer, resolved and closed.
Administrator replies are customer-visible. Internal notes remain private.
Quotation System and PDF
Request flow
A quotation request uses the same country, business and service routing model as support cases. The customer can provide a commercial brief, budget, timeline, preferred currency, contact preference and attachments.
Administrator quote builder
The administrator can:
- add unlimited line items
- set quantity and unit price
- set base currency
- apply a fixed discount
- set tax percentage
- set quotation validity
- add customer-visible terms
- maintain private commercial notes
- save drafts
- send the formal quotation
Status flow
requested → under_review → draft → sent → revision_requested / accepted / declined → closed
PDF and email
The PDF engine generates an A4 quotation without Composer, browser automation or server binaries. When the quote is sent, the system can:
- calculate subtotal, discount, tax and total
- generate the PDF
- attach the PDF to the email
- provide a secure online view
- record status history
- log email delivery
The PDF filename is based on the Quote ID. Formal amounts remain in the administrator-selected base currency.
AI Business Agents
Agent model
Each agent is independent and can have its own:
- business name and website
- logo
- widget key and allowed origins
- colour, launcher style, size and position
- welcome message and suggested questions
- system instructions
- knowledge library
- provider mode
- conversations
- support-form handoff
- optional read-only data lookups
Training options
- Single Q&A entry
- CSV import
- JSON import
- Tab-separated bulk paste
- Question / Answer / Keywords blocks
- Export to CSV
Use the included AI-KNOWLEDGE-IMPORT-TEMPLATE.csv and JSON example.
Answer modes
- **Knowledge only** — approved Q&A only; no external model required.
- **Hybrid** — retrieved approved knowledge grounds the model response.
- **AI only** — model-led response under the configured system instruction.
Knowledge-only mode is the safest default for compliance-sensitive businesses.
Provider security
Provider keys are encrypted at rest and never included in embed code. The global provider is disabled in a fresh installation. Configure a provider only from the administrator portal over HTTPS.
Human handoff
Agents can create a normal support case and attach the conversation context, allowing the customer to continue through the standard Desk workflow.
Read-only database connections
The data connector accepts only administrator-defined, parameterised SELECT queries against explicit allowlisted tables. Use a dedicated database user with SELECT permission only and preferably expose restricted views rather than operational tables.
SMTP and Email
Per-business SMTP
Open Brands & SMTP, select a business and configure:
- host
- port
- encryption (`tls`, `ssl` or none where supported)
- username
- password
- From name
- From email
- Reply-To
- notification recipients
- enabled/disabled state
Passwords are encrypted before database storage. Leaving a saved password field blank during later edits preserves the stored password.
Email types
- Customer OTP
- Case acknowledgement
- Case reply notification
- Quote acknowledgement
- Formal quote with PDF
- Quote conversation notification
- Administrator submission notification
- AI handoff case notification
Delivery troubleshooting
- Verify sender/domain authorization with the SMTP provider.
- Confirm port and encryption match exactly.
- Confirm outbound SMTP is allowed by the host.
- Review Email Logs and the private application log.
- Test with one recipient before enabling all businesses.
No real SMTP credentials are shipped with the commercial package.
Embed Integration
Support forms
Open Forms & Embed, choose a form and copy the generated responsive embed code. Add every website origin that is allowed to frame and submit the form. Regenerating the form embed key invalidates all previous code.
Quote form
Open Quote Settings and copy the recommended JavaScript embed:
<script src="https://support.example.com/assets/v2/quote-embed.js"
data-emaila-quote
data-min-height="760"></script>
A direct iframe fallback is also available through /quote/embed/.
AI agent
Create an agent, save it, then copy the generated one-line JavaScript code from the Deploy section. The widget runs inside an isolated iframe and appears at the configured left or right bottom position.
Common iframe failure
“Refused to connect” usually means one of these:
- a secure page that intentionally blocks framing was used instead of the embed route
- the external origin is not allowlisted
- the quote code still points to `/quote/` instead of `/quote/embed/`
- a server/CDN adds a global `X-Frame-Options` header
Secure case, quote, attachment and administrator pages should not be iframe-enabled.
Demo Source and Installation
The demo-source ZIP is intended for a separate public evaluation subdomain and an empty database.
Install
- Create a separate subdomain such as `demo-support.example.com`.
- Create an empty database.
- Upload the demo-source ZIP directly to the document root.
- Visit `/install/`.
- The installer automatically selects the Emaila showcase and enables demo safeguards.
- The suggested credentials are:
- Administrator: demo.admin@example.com / DemoAdmin!2026
- Customer: demo.customer@example.com / DemoCustomer!2026
- Complete installation and open `/demo/`.
- Delete or rename `install/`.
Safeguards
Demo mode disables administrator writes, outbound email and file uploads. The included records are fictional. The AI agent runs in knowledge-only mode and has no external provider key.
Reset demonstration records
From the command line in the product root:
php tools/reset-demo.php
The reset tool refuses to run when demo mode is disabled.
Publishing a demo
- Change suggested credentials when appropriate.
- Update `/demo/index.php` when different credentials are used.
- Use a separate database and subdomain.
- Add HTTP authentication or IP restrictions while preparing the demo.
- Never connect the demo to production SMTP, production AI keys or production business databases.
Security and Hardening
Required production controls
- Use HTTPS with a valid certificate.
- Delete or rename the `install/` directory after installation.
- Keep `storage/installed.lock`.
- Protect `app/config.local.php`; the included `app/.htaccess` denies web access.
- Use a unique database user restricted to the Desk database.
- Use a strong administrator password and a private administrator URL where desired.
- Back up uploads and database together.
- Keep PHP and the web server patched.
Application controls
- CSRF protection on state-changing forms
- password hashing using `PASSWORD_DEFAULT`
- hashed OTP codes and expiry
- login throttling
- high-entropy tracking and embed keys
- prepared database statements
- MIME/extension upload validation
- denied direct web access to storage
- encrypted SMTP, provider and connector passwords
- private administrator notes
- audit and email logs
- read-only SQL validator for AI connectors
Content Security Policy
The application sets practical security headers. A strict site-wide CSP can be added at the proxy or web-server level after testing embeds, provider calls and inline scripts used by the current theme.
Database connectors
Never connect an AI agent using a database owner account. Create a dedicated SELECT-only account and use restricted views containing only fields safe to disclose to verified customers.
Backup and Restore
What to back up
- Complete MySQL/MariaDB database
- `app/config.local.php`
- `storage/attachments/`
- `storage/v2/support/`
- `storage/v2/quotes/`
- `assets/uploads/brands/`
- `assets/uploads/ai-agents/`
- `assets/uploads/v2-businesses/`
Backup consistency
For a consistent recovery point, temporarily place the portal in maintenance mode, export the database, then archive upload directories. Case and quote records can reference uploaded files; both must come from the same backup window.
Restore
- Create a replacement database and import the database backup.
- Restore source code and uploaded files.
- Restore or update `app/config.local.php`.
- Confirm database privileges and URL.
- Clear cache and open System Check.
- Test administrator login, customer access, file download and email.
Never restore a public demo database over a production database.
Troubleshooting
404 at the bare domain
- Confirm `index.php` exists directly in the configured document root.
- Confirm the subdomain points to that directory.
- Do not leave the source inside an extra `public_html` or version folder.
- Confirm `DirectoryIndex index.php` is accepted.
HTTP 500
- Open `/deployment-check.php` and the administrator System Check.
- Confirm `app/config.local.php` exists and contains correct database details.
- Confirm PDO MySQL is enabled.
- Review `storage/logs/emaila-desk.log` and the hosting error log.
- Confirm the database migration completed.
- Clear OPcache after replacing PHP files.
Forms do not open
- Confirm active brands, forms and form fields exist.
- Use the physical route `/form/?brand=...&form=...` when rewrites are unavailable.
- Confirm allowed origins for external embeds.
- Review browser developer tools for blocked iframe or JavaScript requests.
OTP not received
- Confirm an enabled SMTP profile.
- Verify sender authorization.
- Check spam and Email Logs.
- Demo mode intentionally disables outbound email.
Quote PDF fails
- Confirm the quote exists and the administrator has access.
- Check that item descriptions contain characters supported by the built-in PDF font.
- Review the application log.
AI widget does not load
- Confirm the agent is active.
- Confirm the website origin is allowed.
- Replace old code after regenerating the widget key.
- For AI-generated answers, confirm the provider is enabled and outbound HTTPS works.
White-Label and Reselling Guide
Branding configuration
The installer writes the company and portal name to app/config.local.php. Logo and icon files can be replaced or their paths changed in the same configuration.
Main options:
'branding' => [
'company_name' => 'Your Company',
'portal_name' => 'Unified Support Desk',
'logo_path' => 'img/logos/your-logo.png',
'icon_path' => 'img/logos/your-icon.png',
'primary_color' => '#0d63ce',
'footer_text' => 'Your Company — Unified Support Desk',
],
Replace business logos and showcase records before delivering a white-labelled copy. Do not transfer logos or brand names unless your commercial licence permits that use.
Preparing a customer delivery
- Use the full-source ZIP as the technical base.
- Replace README and support-contact information.
- Define your licence, support period, update policy and number of permitted installations.
- Decide whether source-code modification is allowed.
- State third-party service costs separately; hosting, SMTP and AI-provider fees are not included.
- Include a clean schema and generic starter seed, not a database export from another customer.
Licence template
A configurable LICENSE-COMMERCIAL-TEMPLATE.txt is included. It is a business template, not legal advice. Have local counsel review the final licence before sale.
File and Folder Reference
- `/index.php` — customer portal landing page.
- `/new/` — routed support case wizard.
- `/quote/` — routed quote-request wizard and secure quote view.
- `/search/` — Case ID / Quote ID verification.
- `/client/` — customer activity dashboard.
- `/form/` — public dynamic support form.
- `/embed/` — embedded support form route.
- `/ai/` — AI widget and embed loader.
- `/api/` — AJAX and public API endpoints.
- `/admin/master/` — master administration portal.
- `/app/` — application configuration and business logic; web access denied.
- `/app/v2/` — routed case, quotation, PDF and V2 layout services.
- `/assets/` — public CSS, JavaScript, images and controlled uploads.
- `/database/` — clean schema, seeds, demo data and update SQL.
- `/docs/` — offline documentation.
- `/install/` — fresh web installer; remove after installation.
- `/storage/` — private attachments, quote files and logs; web access denied.
- `/tools/` — command-line maintenance utilities.
- `/marketing/` — product listing and licence templates for the seller.
Frequently Asked Questions
Does it require Composer or Node.js?
No. The runtime is PHP, MySQL/MariaDB, CSS and browser JavaScript. No Composer or npm installation is required.
Is an AI API required?
No. AI agents can run in knowledge-only mode. An external provider is optional.
Can every business use different SMTP?
Yes. Each support brand can have its own SMTP identity and notification recipients.
Can customers reply without creating an account?
Yes. Secure tracking and email verification are supported. A verified account provides a unified dashboard.
Can forms be embedded on other websites?
Yes. Support forms, the quote form and AI widgets have dedicated embed methods.
Does the quote system create PDFs?
Yes. The built-in PHP PDF generator creates formal itemised quotations and can attach them to email.
Can I add countries, businesses and services without code?
Yes. Use the Routing Manager.
Is the database included?
Yes. The product includes a clean schema, generic starter seed, sanitized Emaila showcase, optional demo data and update SQL.
Are SMTP or AI credentials included?
No. All included configuration is intentionally blank or disabled.
Can I host a public demo?
Yes. Use the demo-source ZIP, which enables demo safeguards and includes fictional records.
Product Appendix
Included commercial resources
- README-FIRST.txt and HTML documentation
- Product feature matrix and seller release checklist
- Product listing copy
- Commercial licence template
- Third-party notices template
- Clean schema, seeds, update SQL and demo data
Important limitation
Live database import, SMTP delivery, external AI-provider authentication, domain SSL, server permissions and cross-domain embeds must be tested on the final hosting environment. External services and their fees are not included.