#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.
- Custom JSON-LD schema builder: per-article textarea for arbitrary
structured data with JSON validation. Closes#70
- AI-powered meta generation: Generate with AI buttons for OG title
and description, supports Claude and OpenAI APIs. Closes#71
- XML sitemap: auto-generates sitemap.xml on article save, respects
noindex directives. Closes#72
- Per-platform image resizing: Twitter 1200x600, Pinterest 1000x1500,
WhatsApp 400x400 alongside default Facebook 1200x630. Closes#74
- DB migration 01.05.00: adds custom_schema column
- Rename project source directory from src/ to source/
- Update CI workflows (ci-joomla, pr-check, repo-health) to check
source/ first, falling back to src/ and htdocs/ for compat
- Update .gitignore vendor exception path
- manifest.xml entry-point already updated
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>