Files
MokoSuiteOpenGraph/ISSUES.md
T
Jonathan Miller 433ecfea71 fix: resolve 3 v1.0 release blockers (#47, #48, #39)
- 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
2026-06-21 10:02:03 -05:00

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.php
  • source/packages/com_mokoog/src/ContentType/HikaShopAdapter.php
  • source/packages/com_mokoog/src/ContentType/K2Adapter.php
  • source/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.


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.php
  • source/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->_links access (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