fix(installer): verify install success before showing success #256

Merged
jmiller merged 2 commits from fix/installer-success-detection into dev 2026-07-06 16:15:35 +00:00
Owner

Summary

Joomla installers are lenient: a failed sub-step is logged but postflight still runs, so any success/license/next-steps message can lie. This gates the success path in both installer scripts.

Package script (source/script.php, pkg_mokosuitecross)

  • Adds missingChildExtensions() which reads the package manifest via getParent()->getManifest() and verifies each declared <file> child is registered in #__extensions (match element+type, plus folder=group for plugins).
  • If any are missing: enqueue an error listing them and return before warnMissingLicenseKey().
  • Unconditional housekeeping (download-key restore, core-plugin enable, PerfectPublisher migration detection) still runs regardless of outcome.

Component script (source/packages/com_mokosuitecross/script.php, com_mokosuitecross)

  • Postflight was empty. Adds missingTables() which parses the installed sql/install.mysql.sql for every CREATE TABLE and verifies each exists (prefix-substituted, case-insensitive against getTableList()).
  • On missing tables: enqueue an error and return before the success/license notice; otherwise show the install-success message.

Safety

  • Both checks fail open (try/catch returning []) so a glitch never turns a good install into a false failure.
  • Extension names are htmlspecialchars()-escaped; table/child lists are derived dynamically (nothing hardcoded).

php -l passes on both files.

https://claude.ai/code/session_01MrxXW9iyuDda5yDZrjZMbF

## Summary Joomla installers are lenient: a failed sub-step is logged but postflight still runs, so any success/license/next-steps message can lie. This gates the success path in both installer scripts. ### Package script (`source/script.php`, pkg_mokosuitecross) - Adds `missingChildExtensions()` which reads the package manifest via `getParent()->getManifest()` and verifies each declared `<file>` child is registered in `#__extensions` (match `element`+`type`, plus `folder`=`group` for plugins). - If any are missing: enqueue an error listing them and `return` before `warnMissingLicenseKey()`. - Unconditional housekeeping (download-key restore, core-plugin enable, PerfectPublisher migration detection) still runs regardless of outcome. ### Component script (`source/packages/com_mokosuitecross/script.php`, com_mokosuitecross) - Postflight was empty. Adds `missingTables()` which parses the installed `sql/install.mysql.sql` for every `CREATE TABLE` and verifies each exists (prefix-substituted, case-insensitive against `getTableList()`). - On missing tables: enqueue an error and `return` before the success/license notice; otherwise show the install-success message. ### Safety - Both checks **fail open** (try/catch returning `[]`) so a glitch never turns a good install into a false failure. - Extension names are `htmlspecialchars()`-escaped; table/child lists are derived dynamically (nothing hardcoded). `php -l` passes on both files. https://claude.ai/code/session_01MrxXW9iyuDda5yDZrjZMbF
jmiller added 2 commits 2026-07-06 03:56:13 +00:00
fix(installer): verify install success before showing success
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 30s
60a9d81e22
Gate the success/license path in both installer scripts so a partial
install can no longer report success.

- Package script (pkg_mokosuitecross): add missingChildExtensions(),
  which reads the package manifest via getParent()->getManifest() and
  verifies each declared <file> child is registered in #__extensions
  (matching element+type, plus folder=group for plugins). If any are
  missing, enqueue an error and return before warnMissingLicenseKey().
  Housekeeping (download-key restore, core-plugin enable, PerfectPublisher
  migration detection) still runs unconditionally.
- Component script (com_mokosuitecross): postflight was empty. Add
  missingTables(), which parses the installed sql/install.mysql.sql for
  every CREATE TABLE and verifies each exists (prefix-substituted,
  case-insensitive). On any missing tables, enqueue an error and return
  before the success message; otherwise show install-success/license notice.

Both checks fail open (try/catch returning []/true) so a glitch never turns
a good install into a false failure. Extension names are htmlspecialchars'd.

Claude-Session: https://claude.ai/code/session_01MrxXW9iyuDda5yDZrjZMbF
chore(version): pre-release bump to 01.13.06-dev [skip ci]
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
e7b0cf15cc
jmiller merged commit e5ed21ca68 into dev 2026-07-06 16:15:35 +00:00
jmiller deleted branch fix/installer-success-detection 2026-07-06 16:15:35 +00:00
Sign in to join this conversation.
No Reviewers
Priority -
Type -
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoSuiteCross#256