* Use Request object instead of superglobals
* Use Request in locale resolution
* Queue cookies and remove direct header writes
* Fix flaky i18nTest: de_DE locale isn't installed in CI
CI builds with INSTALL_TRANSLATIONS=false, so only en_US exists on
disk and getLocales() never considers de_DE "enabled". Use en_US as
the cookie value (always installed) against a different config
default to still prove the cookie takes precedence.
* Allow admins to edit ticket replies, with edit history (#2317)
Admins previously had no way to fix a typo or correct a reply without
editing the database directly. Adds an Edit action to admin-authored
messages in the admin ticket view; client-authored messages remain
uneditable so an admin can never alter a client's own words.
Every edit snapshots the message's prior content into a new
support_ticket_message_history table before overwriting it, so the
original wording sent to a client is never silently lost. Admins can
view a message's revision history via a lazy-loaded modal.
Also fixes ticket_message_update, which existed but was never wired
into any UI and skipped the markdown sanitization that ticket_reply
already applies.
* Bump fresh-install last_patch to 83
Fresh installs seed last_patch from content.sql so the patcher doesn't
try to reapply migrations already baked into structure.sql. Missed
bumping this when patch83 (support_ticket_message_history) was added.
* Fix message history modal getting stuck on Loading... after a failed fetch
dataset.loaded was set before the API call resolved, so a failed
request left the modal permanently stuck on "Loading..." with no way
to retry short of a page reload. Move the flag to the success
callback and add an error handler that shows a retryable message.
* Make support_ticket_message_history.support_ticket_message_id required
A history row is meaningless without the message it snapshots; allowing
NULL let orphaned rows exist. Tightened the column in patch84,
structure.sql, and the entity's JoinColumn to NOT NULL.
* Delete message edit history when a ticket is removed
Service::rm() explicitly removes a ticket's notes and messages rather
than relying on the entity mapping's onDelete: CASCADE, because this
schema has no real FK constraints anywhere (referential integrity is
handled at the application layer throughout this codebase). History
rows were missed by that pattern and were left orphaned after a ticket
delete. Now removed alongside their message, following the same
explicit-cleanup convention as notes/messages.
Also cache SupportTicketMessageHistoryRepository via setDi(), matching
every other repository on this service, and add direct coverage for
getMessageHistory().
Previously an email template's "enabled" flag was the only way to control
whether a staff notification (new order, ticket, signup, etc.) went out, and
when enabled it always went to every active staff member. This adds a
per-template staff-group allow-list so notifications can be scoped to the
teams that should actually receive them.
- New email_template_group join table/entity linking templates to admin
groups, with admin API endpoints and a UI card on the template page
mirroring the existing staff-member group management UI.
- Email\Service resolves to_staff recipients from the template's assigned
groups; a template with no groups assigned sends to nobody.
- Existing and newly-created built-in staff templates are auto-linked to
every current staff group (via an UpdatePatcher migration and
createBuiltinTemplateRecord) so upgrades and fresh installs keep today's
"notify everyone" behavior by default.
- Staff\Service::deleteGroup() now blocks removing a group that's still
restricting an email template.
Closes#1247
* Redo and migrate the Admin Group structure
* Update permisison checks to use groups
* Migrate admin group CRUD to Doctrine
* Remove legacy permission and group membership logic
* Replace legacy role logic
* Drop the admin.permissions column
* Only allow super admins to create/edit/delete groups, better guards
* Remove the redundant `admin.protected` column
* Clean group memberships when an admin is deleted
* Make the "Exclude cron user" filter work
* Improve labels
* Addressed code review comments
* Require an initial group
* Improved logger messages
* Replace role subtitle with email
* Bypass permission checks during update finalization to make sure it's accessible
* More sensible default groups
* Update seed content timestamps
* Fixed tests
* Cron login guard
* Addressed code review comments
* Change permission column type to JSON
* Addressed code review comments
* Migrate regular staff to a temporary group and disallow groupless staff management
* Look for Super Administrator or legacy `admin` role
* Fixed tests
* Changed test name to make cspell happy
* Grant required permissions to the groups
---------
Co-authored-by: Adam Daley <admdly@users.noreply.github.com>
* Migrate Email, Extension, Support modules to Doctrine ORM
* Add 'initialises' to cspell.json custom words
* Add patch76 and fix extension deactivation event
* Bump database patch version to 76
* Refactor Support APIs to mapped Doctrine flows
* Handle legacy email queue and ticket filters
* Migrate Support module to Doctrine ORM
* Refactor services to use typed repositories
* Route order ticket count and ticket messages through repositories
Drops the last two thin Support\Service wrappers, calling the
SupportTicketRepository and SupportTicketMessageRepository directly
from the cross-module callers.
* Rename email queue table and add patch
* Preserve unlimited email queue processing
* Preserve unlimited email queue processing
* Migrate the knowledge base to Doctrine
* Addressed code review comments
* Move incrementViews to the repo
* Knowledge base suggestions in support forms
* Improve the UI and make search actually search
* Make the knowledge base enabled on new installs by default
* Redid the kb index to list articles alongside categories
* Display articles in admin manage category
* Redirect authenticated users from guest ticket page to client ticket page
* Address code review comments
* Addressed code review comments
* Improved search accuracy by tokenizing queries
* Updated article layout and added CTAs
* Added a setting to toggle view count's visibility
* Removed contact button from the sidebar
* Migrate canned responses to Doctrine and improve admin UI
* Improved support settings canned dropdowns
* Added a flag to hide view count when serializing
* Improved search query matching
* Migrate SupportHelpdesk to Doctrine
* Fixed tests
* Update copyright headers
* Implemented suggestions (credit @admdly)
* Remove dead test
* Improve type safety, auth checks and PHPStan fixes (#3250)
* Improve type safety, auth checks and PHPStan fixes
* Remove @phpstan-ignore annotations
* Improve type safety, auth checks and PHPStan fixes
* Remove @phpstan-ignore annotations
* Remove redundant @phpstan-ignore comment
* Improve code robustness and reliability (#3248)
* Harden code against null/undefined values
* Update dependency lockfiles
* Sanitize ticket input and use IDs in email list
* Restructure tests and add test utilities
* Move E2E tests to `Library\E2E` namespace
* Update `php-build` action ref in workflows
* Switch tests to Pest and add test scaffolding
* Refactor E2E tests to Pest-style tests
m
Skip E2E tests when env not configured
* Refactor Unit tests and update test config
Add test datasets and refine test helpers
* Add DEBUG guard, fix API JSON decode, update tests
* Refactor tests: add types and Mockery expectations
* Adjust tests, phpstan config, and composer script
* Instantiate test APIs locally, remove beforeEach
* Refactor runtime checks, types & logging
* Apply PHP Code Styling Changes
m
* Add PHPStan ignores, test renames & small fixes
* Enable Pest tests in CI workflow
* Remove legacy tests; add new unit tests/config
* Avoid undefined index in fingerprint comparison
* Ignore properties absent in both fingerprints
* Remove public_ticket_create API method
* Add Fingerprint unit tests
* Remove em dash from fingerprint test name
* Switch to Pest; assorted bug fixes & refactors
* Prefer getDi() and guard DEBUG define
* Refactor tests: DBAL, Antispam rename, helpers
* Refactor email tests to use Doctrine entities
* Update tests, use DBAL mocks & improve Formbuilder admin
* Validate plan_id and update unit tests
* Replace error_log with DI logger and update tests
* Expect db->store in Invoice Service test
* Use DI logger instead of error_log; fix tests
* Fix typo in Hook Service test
* Fix Staff test spelling fixture
* Complete Pest test migration
* Fix Product test spelling fixtures
* Fix Product test spelling fixtures
* Run live tests with Pest and load helpers
* Migrate tests to ApiClient; remove legacy APIHelper
* Fix Email test spelling
* Remove unused PHPUnit bridge
* Organize Cypress end-to-end tests
* Document Pest test directory root
* Remove noisy Pest comments