Joomla 5 module templates don't have $this — data comes via extracted
variables from getLayoutData(). Replace $this->escape() with
htmlspecialchars() and remove $app reference.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
┌────────────────────────────────────────────────────────────────────┐
│ version_read v04.00.15 │
│ Read version — manifest.xml is canonical, falls back to README.md and Joomla XML│
└────────────────────────────────────────────────────────────────────┘
02.32.04 [skip ci]
Admin dashboard module (mod_mokowaas_cpanel) showing:
- MokoWaaS version, debug/offline status badges
- Health indicator (database connectivity check)
- Feature plugin status badges (enabled/disabled)
- Link to full MokoWaaS control panel
- Auto-assigns to cpanel position on install
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
┌────────────────────────────────────────────────────────────────────┐
│ version_read v04.00.15 │
│ Read version — manifest.xml is canonical, falls back to README.md and Joomla XML│
└────────────────────────────────────────────────────────────────────┘
02.32.03 [skip ci]
Joomla 5 expects one <namespace> with the base path — it auto-appends
\Administrator and \Api based on context. Having two <namespace> elements
caused manifest_cache to store only the first, breaking the other context.
Also fixes CI auto-bump mangling the <version> tag.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
┌────────────────────────────────────────────────────────────────────┐
│ version_read v04.00.15 │
│ Read version — manifest.xml is canonical, falls back to README.md and Joomla XML│
└────────────────────────────────────────────────────────────────────┘
02.32.02 [skip ci]
- GET /api/v1/mokowaas/plugins — list all MokoWaaS feature plugins + status
- POST /api/v1/mokowaas/plugins — toggle a feature plugin on/off
- GET /api/v1/mokowaas/dashboard — combined site info + plugin states summary
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
┌────────────────────────────────────────────────────────────────────┐
│ version_read v04.00.15 │
│ Read version — manifest.xml is canonical, falls back to README.md and Joomla XML│
└────────────────────────────────────────────────────────────────────┘
02.32.01 [skip ci]
- Add admin dashboard to com_mokowaas with site info bar, feature plugin
grid with AJAX toggles, and quick actions (clear cache, check updates)
- Split monolithic system plugin into 4 toggleable feature plugins:
Firewall, Tenant Restrictions, DevTools, and Health Monitor
- Add MokoWaaSHelper utility class for shared master-user detection
- Add static updates.xml (licensing system deferred)
- Restore universal moko-platform workflows
- Add param migration in package script for existing sites
- Fix license key warning to show once per session
- Rename license key messages to "Moko Consulting License Key"
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap all syncpush inserts in try/catch to skip duplicates instead
of failing the entire batch. Add metadata column to categories.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fulltext is a MySQL reserved word — must be backtick-quoted.
Menu items require path column for Joomla routing.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sync methods now use $this->targetUrl and $this->healthToken instead
of function parameters that no longer exist after the bulk push refactor.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The global API token check reads from query string/header, but
syncclear and syncpush send the token in the JSON POST body.
Skip the global check for these actions.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All sync communication (syncclear, syncpush) authenticates via the
target's MokoWaaS health token. Joomla API token is not needed.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The syncclear/syncpush endpoints authenticate with the target site's
health token. Added health_token field to task config. Removed
api_user field (unused). Removed getHealthToken (read from source).
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After bulk-inserting content, the target site now:
- Rebuilds category and menu nested set trees (lft/rgt/level)
- Creates #__assets entries for articles and categories (ACL)
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of individual Joomla API POST calls per article (84 calls),
the sync task now sends items in batches of 50 to the target's
/?mokowaas=syncpush endpoint which inserts directly via DB.
Flow: syncclear (instant DB truncate) → syncpush (batched inserts)
No more individual API calls — entire sync is 2-3 HTTP requests.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added /?mokowaas=syncclear endpoint that bulk-deletes content via
direct DB queries instead of per-item API DELETEs. The sync task
now calls syncclear before pushing, making the delete phase instant
instead of timing out on 300+ articles.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After deleting items, remaining items shift down. Incrementing the
page offset skipped items. Now always fetches page 0 until empty.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The url field type was causing validation issues preventing save.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Joomla's TaskPluginTrait only saves params from the fieldset matching
the form name. Multiple fieldsets caused fields to not persist.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Existing tasks without target_url/api_token filled in could not be
saved. The task handles empty values at runtime instead.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Site alias is now hardcoded to dev.{primary_domain}
- dev.* subdomain bypasses offline mode for development access
- dev.* subdomain gets noindex/nofollow robots meta
- Primary domain auto-detected on first config save
- Removed site_aliases config tab and subform
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dev mode ON:
- Disable caching, enable Joomla debug + MokoOnyx template debug
- Show offline page on primary domain (site aliases bypass for dev work)
- Suppress article hit recording
Dev mode OFF (toggled via config save):
- Clear content version history
- Reset all article hits
- Disable template debug
- Take site back online
Also: merged diagnostics + maintenance into default config tab.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only enforce users in MASTER_KEYS — don't auto-delete other users.
Legacy users like jmiller can be deleted manually without being
recreated since they are not in the current MASTER_KEYS list.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Version bump across all manifests and docs
- Auto-cleanup of legacy master users no longer in MASTER_KEYS
- Updated CHANGELOG with all 02.31.00 changes
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each sync task instance now has its own target URL, API token, and
content type toggles. Sync strategy is delete-then-push via the
Joomla API for articles and menus (avoids duplicates, respects ACL).
Content types: articles, categories, menus, modules
File types: images/, files/, media/ (via MokoWaaS sync-receive endpoint)
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Persistent admin warning when no download key is set on the MokoWaaS
update site, with link to System → Update Sites
- Daily heartbeat validates the key against MokoGitea's dynamic endpoint;
shows error if key is invalid or expired
- Package postflight removes stale/duplicate update site entries and
orphaned #__updates rows
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update server now points to MokoGitea's dynamic endpoint which
validates license keys (dlid) and generates update XML from git
releases. Users enter the download key via Joomla's native
System → Update Sites interface. Legacy static URLs are auto-migrated
on install/update.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only enforce the primary master username; plugin no longer creates
or protects the secondary user account.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hardcode mokoconsulting and jmiller as master usernames (no longer
configurable via params)
- Fix isIpAllowed() reading from global config instead of plugin params
- Fix empty allowed_ips returning false (now allows all IPs)
- Both master users are auto-created and enforced as Super Admins
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>