- CHANGELOG: fix the mangled header (duplicate empty [01.05.00], misplaced
intro) and add a full [Unreleased] section covering the dashboard, edit UI,
CSV import UI, access.xml/config.xml, AI/sitemap hardening, forward-compat,
dead-code removal, and the new unit tests
- README: add Coverage dashboard / Manual tag editor / Component permissions to
Admin Tools; drop the removed ImageGenerator overlay feature; note sitemap
access-level filtering; add a Joomla 6.0+ / PHP 8.2+ Requirements line
- New DashboardModel (BaseDatabaseModel) with getStats(), getCoverageByType(),
getMissingArticles() — coverage logic moved out of the list template
- New View/Dashboard/HtmlView + tmpl/dashboard/default.php: SVG donut coverage
gauge, field-gap badges, per-content_type breakdown table, and a list of
published articles missing OG tags (linking to the article editor) with a
Batch Generate shortcut
- DisplayController default_view -> dashboard; Dashboard + Tags submenu entries
- Removed the inline coverage.php include from the tags list (it ran 6 uncached
COUNT queries on every list load); that logic now lives in DashboardModel
- Declared tmpl/dashboard in the manifest; added language strings (en-GB, en-US)
#95 — ACL + Options:
- Add access.xml (core actions + mokoog.batch / mokoog.import custom actions)
- Add config.xml (Permissions tab + note pointing settings to the system plugin)
- Declare both in the manifest; Batch/ImportExport controllers now check the
custom actions with a fallback to the prior core checks (no lockout)
#103 — CSV import is now reachable:
- Add an Import toolbar button that toggles a multipart file-upload form
(jform[csv_file]) posting to importexport.import with a CSRF token
#104 — Dead code + disk leak:
- Delete unused ImageGenerator class and JsonLdBuilder::buildOrganization()
- Add ImageHelper::pruneOldFiles() (deletes generated images older than 30d)
and call it on content save so the generated-image cache is bounded
#107 — Packaging:
- Declare language/en-US in the component manifest (was never installed)
- Remove undeclared empty stub dirs src/Field, src/Service
#99 — AI AJAX endpoint hardening:
- require core.edit/core.create on com_content before generating (was
reachable by any authenticated back-end user → paid-credit abuse)
- callAiApi: 20s timeout + HTTP status check (throw on non-200) instead of
silently returning an empty string
#100 — Sitemap information disclosure + robustness:
- filter to public (guest) view levels so registered/special-access
articles are never written into the public sitemap
- atomic write (temp file + rename) so concurrent saves can't expose a
half-written sitemap.xml
- (throttling + SEF URLs remain follow-ups, noted on the issue)
#101 — Expose newer columns in CSV + API:
- og_video, event_data, recipe_data, custom_schema added to CSV export/import
(appended, so existing CSVs still import) and to the REST API field whitelist
- import validates JSON fields as arrays/objects and og_video as http(s)
(prevents re-introducing the #97 scalar-JSON-LD crash via import)
#102 — Forward-compat (complete):
- Factory::getLanguage() -> getApplication()->getLanguage() (4 sites)
- Joomla\CMS\Filesystem\File/Folder -> Joomla\Filesystem\* (ImageHelper, ImageGenerator)
#106 — partial: loadArticle() now caches null misses (array_key_exists),
getArticleDate() skips 0000-00-00 dates. Batch-JS halt deferred — the
offset=0 design re-fetches failed rows, so the created>0 guard prevents an
infinite loop; a safe fix needs cursor-based pagination in BatchController.
#97 — Fatal frontend 500 from scalar custom_schema:
- MokoOGContent::validateJson() now requires a JSON object/array (rejects
scalars like 42/"x"/true that previously passed and were stored)
- MokoOG render path guards with is_array($decoded) so already-stored
scalar payloads can no longer crash the public page
#98 — Missing single-tag create/edit admin UI:
- Add Controller/TagController (FormController), View/Tag/HtmlView, tmpl/tag/edit.php
- Link OG title in the list to the editor; add New/Edit toolbar buttons
- Declare tmpl/tag folder in the component manifest
- tag.xml: switch cross-package PLG_CONTENT_* labels to COM_MOKOOG_* keys,
make content_type/content_id editable+required (enables New), add language field
- Add the new COM_MOKOOG_* strings to en-GB and en-US
Also fixes#77 while here: seo_title/meta_description form maxlength now
match the DB columns (70/200) instead of 255.
Removes accessors deprecated in Joomla 5 and slated for removal in 7
(extension already runs on 6; this future-proofs for 7):
- Factory::getDbo() -> Factory::getContainer()->get(DatabaseInterface::class)
across plugins, controllers, static helpers, and the install script
- Factory::getUser() -> Factory::getApplication()->getIdentity()
- Factory::getSession() -> Factory::getApplication()->getSession()
- jexit(Text::_('JINVALID_TOKEN')) -> throw new \RuntimeException(..., 403),
consistent with the access-denied checks already in those controllers
Note: SQL update-version concern is already resolved — the release bumped
to 01.05.00, which matches the 01.05.00.sql update slot.
Product rename (display name / docs / comments / language strings only —
technical element names mokoog/com_mokoog/MokoOG namespace unchanged):
- Replace "MokoJoom" -> "MokoSuite" across 55 files
- Fixes the update-site license lookup in script.php, which matched the
old "%MokoJoomOpenGraph%" name and would never find a "MokoSuite" site
Joomla 6 compatibility:
- script.php: minimumJoomla 4.0.0 -> 6.0.0, minimumPhp 8.1.0 -> 8.2.0,
and actually enforce the Joomla floor in preflight() (was PHP-only)
- Add PKG_MOKOOG_JOOMLA_VERSION_ERROR language strings (en-GB, en-US)
- openapi.yaml + README state Joomla 6.0+ requirement
- Audit confirmed the codebase already uses only Joomla-6-supported APIs