Skip to content

[3.x] Form handler refactor to allow more flexible and accurate status reporting in the manager UI - #17023

Draft
smg6511 wants to merge 11 commits into
modxcms:3.xfrom
smg6511:3.x-form-handler-refactor
Draft

smg6511 wants to merge 11 commits into
modxcms:3.xfrom
smg6511:3.x-form-handler-refactor

Conversation

@smg6511

@smg6511 smg6511 commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

What changed and why

Rewires the MODx.form.Handler (js) methods and associated backend methods to:

  • support reporting of intermediate statuses (i.e., warning and info) via customizable dialog titling and styling that matches each state (style is only minimally applied in this PR by assigning the associated icon for each status in the dialog body; more fine-tuned/elegant styling will be the job of a separate PR);
  • allow intermediate statuses to route to success or failure, depending on which is more appropriate;
  • allow HTML in dialog messages via a new MODx.form.Handler.showFormattedMessage method, which is opt-in and does not affect any of the current success/failure messaging unless explicitly changed in the back end logic by using the new Processor::status method [e.g., instead of $this->failure(...), one would use $this->status(...) with the messageIsFormatted param set to true]; and
  • in the case of HTML dialogs, match the front and back end sanitization rules via backend constants that are relayed to the front end in new MODx.config props.

In support of the HTML dialog option, two new php utilities were added as services (modStringSanitizer and modStringConverter). Note that:

  • Although these were purpose-built for this PR, they can be useful and are accessible for consumption outside the core.
  • Their classes were envisioned to house other related utils over time. Particularly, there are many util methods in the modX base class, the Processor class, and probably elsewhere that can be more appropriately located in these utility classes.

There are many instances where a failure is not a failure per se, but we've only had an unrealistic binary success or failure path for reporting the state of a process in the UI. That, along with the inability to format messages when needed was the motivation for this change.

How to test

This update touches many areas, so I advise a general run through of creating objects and purposely causing failures. One easy way is via any object emits a dialog on validation errors (Resource, Element, etc.).

A specific case in included in this PR to see how the change is applied and to verify it works. See the changes in the final commit of this PR for reference (Packages CheckForUpdates).*

  1. Go to the Extras/Installer (Package Management page) and install a package or two if you have none in your testing install.
  2. Before and after applying this PR, click the Check For Updates button on any of these packages to verify the old against the new behavior.

* To see the effects of the new behavior under different scenarios, make changes in CheckForUpdates ~L97-98+; play with the message itself and the $this->status (new) vs $this->failure (existing) statement. An example of what I used to test:

For checking support of html in message, and full stripping of it when not in formatted mode:

$msg = <<<HTML
    <strong>Special Message</strong><br>
    <span>It's a special intro:</span><br>
    <em>{$msg}</em>
    <script>return 'do something bad';</script>
HTML;
return $this->status(
    $msg,
    $this->modx->lexicon('package_status'), // <- change the window title
    Processor::STATUS_TYPE_WARN, // <- change for various status types (_ERROR, _INFO)
    true // <- change for formatted vs unformatted (false)
);

Related issue(s)/PR(s)

Although not specifically created for this, the included verification case (CheckForUpdates) illustrates this PR's way of handling what's addressed in #17000.

Compatibility notes

n/a

Breaking change assessment

No BC anticipated, as current behavior is preserved and handler methods marked as deprecated pass through to new methods at least until 3.4 when removal is suggested.

Test coverage

New UT for stripHTML method located in Tests/Utilities/Sanitizers.

Contributors

n/a

AI tool use

n/a

smg6511 added 11 commits August 27, 2026 10:32
Revert to unchanged file
Remove remaining test logging and add more inline documentation
Remove errant space
Remove stray log
Add utils as a testsuite
Ensure plain text msg source is stripped and make dialog box consistent between html-formatted and plain message boxes.
@smg6511
smg6511 marked this pull request as ready for review September 10, 2026 04:36
@smg6511 smg6511 changed the title [3.x] Form handler refactor to allow more flexible and accurate reporting [3.x] Form handler refactor to allow more flexible and accurate status reporting in the UI Sep 10, 2026
@smg6511 smg6511 changed the title [3.x] Form handler refactor to allow more flexible and accurate status reporting in the UI [3.x] Form handler refactor to allow more flexible and accurate status reporting in the manager UI Sep 10, 2026
@smg6511
smg6511 requested a balanced review from Copilot September 10, 2026 22:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Status routing currently causes compatibility regressions, incomplete package handling, and state leakage across processor responses.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Refactors manager form handling to support typed status dialogs, optional sanitized HTML, and improved package update reporting.

Changes:

  • Adds configurable status responses and dialog routing.
  • Introduces string sanitization/conversion services.
  • Reports “package up to date” as informational and adds sanitizer tests.
File summaries
File Description
manager/assets/modext/workspace/package.grid.js Handles empty update results.
manager/assets/modext/core/modx.js Adds status-dialog routing and formatting.
core/src/Revolution/Utilities/Sanitizers/modStringSanitizer.php Adds HTML sanitization.
core/src/Revolution/Utilities/Converters/modStringConverter.php Adds HTML-to-JSON conversion.
core/src/Revolution/Processors/Workspace/Packages/CheckForUpdates.php Returns informational up-to-date status.
core/src/Revolution/Processors/Processor.php Adds status response API.
core/src/Revolution/modX.php Registers utilities and sanitization configuration.
core/src/Revolution/modConnectorResponse.php Exposes message configuration.
core/src/Revolution/Error/modError.php Stores message configuration in responses.
core/lexicon/en/workspace.inc.php Adds package status title.
core/lexicon/en/default.inc.php Adds dialog-related messages.
_build/test/Tests/Utilities/modStringSanitizerTest.php Tests HTML sanitization.
_build/test/phpunit.xml Registers utility tests.
Review details
  • Files reviewed: 13/13 changed files
  • Comments generated: 11
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +73 to +74
$this->stringSanitizers = $this->modx->services->get(modStringSanitizer::class);
$this->stringConverters = $this->modx->services->get(modStringConverter::class);
'object' => $objarray,
];
'object' => $objarray
], $this->messageConfig);
Comment on lines +34 to +35
/** Status message type: Success */
public const STATUS_TYPE_SUCCESS = 'success';
Comment on lines +413 to +414
case !empty($windowTitle):
$options['messageConfig']['messageWindowTitle'] = $windowTitle;
Comment on lines +98 to +102
return $this->status(
$msg,
$this->modx->lexicon('package_status'),
Processor::STATUS_TYPE_INFO
);
and info messages will typically be sent via a success
rather than failure response.
*/
if (r.message || !Ext.isEmpty(r.messageConfig)) {
Comment on lines +978 to +982
const data = {};
data.title = Object.hasOwn(response.messageConfig, 'messageWindowTitle')
? Ext.util.Format.stripTags(response.messageConfig.messageWindowTitle)
: _('error')
;
Comment thread core/src/Revolution/Processors/Processor.php
* @param string $string The unencoded html string
* @return string The JSON-encoded string
*/
public function htmlToJSON(string $string): string
Comment thread core/src/Revolution/Utilities/Sanitizers/modStringSanitizer.php
@smg6511
smg6511 marked this pull request as draft September 11, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants