- Add TagsController extending AdminController for admin list delete/publish/unpublish operations (#48) - Add language filter to loadOgDataByType() and loadOgDataByMenu() matching the pattern already used in loadOgData() (#47) - Replace direct $doc->_links access with getHeadData()/setHeadData() public API for Joomla forward compatibility (#39) - Update ISSUES.md with full 2026-06-21 assessment
11 KiB
MokoSuiteOpenGraph — Code Assessment Issues
Generated: 2026-06-06 Updated: 2026-06-21 Reviewed: Full codebase (all PHP, SQL, XML, JS, CSS, templates)
Status Legend
- FIXED — Verified resolved in codebase
- OPEN — Still present, needs work
- WONTFIX — Intentional or acceptable as-is
Bugs
BUG-01: Batch generation offset pagination skips articles — FIXED
Severity: High
File: source/packages/com_mokoog/src/Controller/BatchController.php:89
The process() method now correctly uses $db->setQuery($query, 0, $limit) with a comment explaining that processed articles are automatically excluded by the LEFT JOIN filter.
BUG-02: License key session flag set before check completes — FIXED
Severity: Medium
File: source/packages/plg_system_mokoog/src/Extension/MokoOG.php:543
Session flag is now set after the DB query succeeds, inside the try block but after query setup. If the query throws, the catch block runs without the flag being set.
BUG-03: Hardcoded og:image dimensions are often wrong — FIXED
Severity: Medium
File: source/packages/plg_system_mokoog/src/Extension/MokoOG.php:129-134
Now uses $this->getImageDimensions($image) which calls getimagesize() to detect actual dimensions. Dimension meta tags only emitted when dimensions are successfully detected.
BUG-04: strlen() vs mb_strlen() inconsistency in truncation — FIXED
Severity: Low Files: MokoOG.php, BatchController.php, HikaShopAdapter.php, K2Adapter.php
All instances now consistently use mb_strlen() for length checks with mb_substr() for truncation.
BUG-05: ImageGenerator::wrapText() can produce broken output — FIXED
Severity: Low
File: source/packages/plg_system_mokoog/src/Helper/ImageGenerator.php:156
Now checks mb_strlen($lines[2]) > 3 before truncating. Short lines get '...' appended instead.
Potential Issues
ISSUE-01: ContentType adapters exist but are never wired up — OPEN
Severity: High (wasted code) Files:
source/packages/com_mokoog/src/ContentType/ContentTypeInterface.phpsource/packages/com_mokoog/src/ContentType/HikaShopAdapter.phpsource/packages/com_mokoog/src/ContentType/K2Adapter.phpsource/packages/com_mokoog/src/ContentType/VirtueMartAdapter.php
The system plugin (MokoOG.php) still never references or loads these adapters. The findImage() and loadOgData() methods only handle com_content. Third-party content types get no auto-generated OG tags.
Action: Wire adapters into the system plugin's onBeforeCompileHead flow, or remove them if not planned for v1.
ISSUE-02: applySeoTags() accesses internal $doc->_links property — OPEN
Severity: Medium
File: source/packages/plg_system_mokoog/src/Extension/MokoOG.php:257-259
Still directly accessing $doc->_links (protected/internal property). Fragile across Joomla versions.
Fix: Use $doc->getHeadData() to read links and $doc->addHeadLink() with proper clearing logic.
ISSUE-03: No input sanitization on OG values before output — OPEN
Severity: Medium
File: source/packages/plg_content_mokoog/src/Extension/MokoOGContent.php
No htmlspecialchars() or InputFilter found in the content plugin's save path. While Joomla's setMetaData() escapes on output, defense-in-depth recommends sanitizing on input.
Fix: Apply htmlspecialchars() or Joomla's InputFilter when saving OG data.
ISSUE-04: loadOgDataByType() and loadOgDataByMenu() ignore language — OPEN
Severity: Medium Files:
source/packages/plg_system_mokoog/src/Extension/MokoOG.php:324-337(loadOgDataByType)source/packages/plg_system_mokoog/src/Extension/MokoOG.php:346-359(loadOgDataByMenu)
These methods still have no language filter. On multilingual sites, category fallback or menu OG data could come from any language. The unique key is now (content_type, content_id, language) but these queries don't filter by language, so loadObject() returns an arbitrary match.
Fix: Add the same language filter pattern used in loadOgData().
ISSUE-05: VirtueMart adapter interpolates language into table name — OPEN (low risk)
Severity: Low (defense-in-depth)
File: source/packages/com_mokoog/src/ContentType/VirtueMartAdapter.php:34,47
Language tag is interpolated into the table name. While quoteName() wraps the result, the language tag itself is not validated against an allowlist.
Fix: Validate tag format with a regex before interpolation.
ISSUE-06: No admin list controller for publish/delete operations — OPEN
Severity: Medium
File: source/packages/com_mokoog/src/Controller/
No TagsController extends AdminController exists. The admin list view toolbar buttons for delete/publish/unpublish will produce task routing errors.
Fix: Add a TagsController extends AdminController with proper CSRF and ACL checks.
ISSUE-07: CSV import/export does not handle language column — OPEN
Severity: Low
File: source/packages/com_mokoog/src/Controller/ImportExportController.php
No reference to language found in the controller. Export omits the column, import creates records with default * language. Multilingual sites cannot bulk import/export language-specific OG data.
Fix: Add language as a column in export, and parse it on import with a fallback to *.
ISSUE-08: No ACL check in content plugin form injection — WONTFIX
Severity: Low
File: source/packages/plg_content_mokoog/src/Extension/MokoOGContent.php:49
Any user who can edit an article can modify OG tags. This is acceptable behavior for most sites — if you can edit the article, you should be able to control its social sharing appearance.
New Issues (Found 2026-06-21)
ISSUE-09: ImageGenerator uses @ error suppression on GD functions
Severity: Medium
File: source/packages/plg_system_mokoog/src/Helper/ImageGenerator.php
All GD library calls use the @ suppression operator, making debugging difficult. If the GD extension is missing or a font file is not found, failures are completely silent.
Fix: Replace @ suppression with proper error checking and logging via Log::add().
ISSUE-10: No TTF font file bundled or documented
Severity: Medium
File: source/packages/plg_system_mokoog/src/Helper/ImageGenerator.php
The image generator requires a TTF font file for text overlay, but no font is included in the package and no fallback or documentation exists for configuring the font path.
Fix: Bundle a permissively-licensed font (e.g., Open Sans, Noto Sans) or document the required configuration.
ISSUE-11: ImageGenerator cache grows unbounded
Severity: Low
File: source/packages/plg_system_mokoog/src/Helper/ImageGenerator.php
Generated images in images/mokoog/generated/ are never cleaned up. On sites with many articles, this directory grows indefinitely.
Fix: Add a cleanup CLI command or admin button (see FEAT-07), or implement LRU/TTL-based cache eviction.
ISSUE-12: JSON-LD missing common schema types
Severity: Low
File: source/packages/plg_system_mokoog/src/Helper/JsonLdBuilder.php
Only 4 schema types are implemented (Article, WebPage, BreadcrumbList, Organization). Missing: NewsArticle, BlogPosting, Product, VideoObject, Event — some of which correspond to existing og_type dropdown values.
Fix: Add at least NewsArticle and BlogPosting as Article subtypes.
ISSUE-13: No API input validation beyond field whitelisting
Severity: Low Files:
source/packages/com_mokoog/api/src/Controller/TagsController.phpsource/packages/com_mokoog/api/src/View/Tags/JsonapiView.php
The REST API exposes full CRUD but has no validation for field content (e.g., max lengths, valid URLs for og_image/canonical_url, valid og_type values).
Fix: Add validation rules matching the form XML constraints.
Feature Expansion Opportunities
FEAT-01: Wire up ContentType adapter system — NOT IMPLEMENTED
Connect the existing ContentTypeInterface adapters to the system plugin so HikaShop products, K2 items, and VirtueMart products automatically get OG tags. Blocked by ISSUE-01.
FEAT-02: Admin edit view for individual OG tag records — NOT IMPLEMENTED
A TagModel and tag.xml form exist but there's no edit template (tmpl/tag/) or TagController. Users can only manage OG tags through article/menu editors.
FEAT-03: Publish/unpublish toggle in admin list — NOT IMPLEMENTED
Blocked by ISSUE-06 (no TagsController). The list view shows published status as text but has no clickable toggle.
FEAT-04: Actual image dimension detection for og:image meta — FIXED
Implemented via getImageDimensions() method using getimagesize(). See BUG-03.
FEAT-05: Duplicate OG tag detection — NOT IMPLEMENTED
No detection for conflicting OG meta tags from other extensions.
FEAT-06: Support og:video and og:audio URLs — NOT IMPLEMENTED
No og_video or og_audio columns, form fields, or rendering logic found anywhere in the codebase.
FEAT-07: Generated image cache cleanup — NOT IMPLEMENTED
No CLI command or admin purge button. See ISSUE-11.
FEAT-08: Sitemap integration — NOT IMPLEMENTED
No sitemap generation or integration exists.
FEAT-09: Social share preview in admin list — NOT IMPLEMENTED
No thumbnails or inline validation in the admin list view. Live preview only exists in the article/menu editor (via plg_content_mokoog).
FEAT-10: Bulk OG tag editing — NOT IMPLEMENTED
No batch edit modal for selecting multiple items and changing common fields.
Security Fixes (from CHANGELOG [Unreleased])
All 4 claimed security fixes have been verified as implemented:
| Fix | Status | Evidence |
|---|---|---|
| JSON-LD XSS (#34) | IMPLEMENTED | </ escaping in JsonLdBuilder::toScriptTag() |
| ACL on Batch/ImportExport (#37) | IMPLEMENTED | authorise() checks on all controller methods |
| CSV import validation (#35) | IMPLEMENTED | File type, MIME, size (2MB), content_type regex |
| Multilingual data corruption (#41) | IMPLEMENTED | Language-aware load/save in content plugin |
Additional security review found no vulnerabilities for: SQL injection, CSRF, file upload, path traversal, code injection, or XSS in output.
Summary
| Category | Total | Fixed | Open | Won't Fix |
|---|---|---|---|---|
| Bugs | 5 | 5 | 0 | 0 |
| Issues | 13 | 0 | 12 | 1 |
| Features | 10 | 1 | 9 | 0 |
| Security | 4 | 4 | 0 | 0 |
Priority for v1.0.0 Release
Must fix:
- ISSUE-06: TagsController for admin list operations (publish/delete broken)
- ISSUE-04: Language filter on loadOgDataByType/loadOgDataByMenu (data integrity on multilingual sites)
Should fix:
- ISSUE-02: Replace
$doc->_linksaccess (Joomla version fragility) - ISSUE-03: Input sanitization on save (defense-in-depth)
- ISSUE-09: GD error suppression (debuggability)
- ISSUE-10: Bundle or document TTF font requirement
Nice to have for v1.0.0:
- FEAT-02: Admin edit view
- FEAT-03: Publish/unpublish toggle
- ISSUE-07: Language column in CSV import/export