Contents Reference Public

Module Research Notes

Evidence gathered from the current Contents module files — controllers, models, configs, and migrations — before writing these user guide pages.

Guide version: r1 Module version: 1.0.0 Updated: 2026-07-22 Estimated time: 5 min 1 views
Reference

Module Research Notes

Evidence gathered from the current module files before writing the user guide pages.

Slug: contentVersion: 1.0.0Category: ContentsReviewed: 2026-07-11

Research Sources Inspected

Source path

modules/Content

Feature flags marked true

  • Controllers
  • Models
  • Views
  • Libraries
  • Language
  • Permissions
  • Left Menu
  • Default Menu
  • Routes
  • Migrations
  • Cron Jobs
  • Helpers
  • Api Endpoints
  • Components

Evidence Summary

Manifest

module.json defines slug content, version 1.0.0, category Contents, and the module capability flags used in this guide.

Runtime surface

7 controller file(s), 56 view file(s), and 22 route mapping(s) were found.

Data surface

25 model file(s), 28 declared table(s), and 2 migration file(s) were found.

Operations surface

27 permission key(s), 6 job(s), 3 seeder(s), and 20 test file(s) were found.

Detailed File Evidence

Controllers and methods

  • Content
  • Content_admin
  • Content_api - pages, page, posts, post, categories, tags, comments, media
  • Content_euapi - posts, post, page, comments, recommendations, postComment, addReaction, removeReaction
  • Content_feed
  • Content_preview
  • Content_sitemap

Jobs and schedules

  • Aggregate CMS analytics (daily) (15 0 * * *) - Rolls up yesterday
  • Expire lapsed CMS commenter bans (0 * * * *) - Lifts CMS commenter bans whose expiry has elapsed (system lift) and records the unban in the moderation log + audit trail. Permanent bans are left untouched.
  • Publish scheduled CMS content (*/5 * * * *) - Promotes scheduled CMS pages/posts to published once their scheduled time arrives, snapshots the published revision and records the audit event.
  • Regenerate CMS sitemap (0 4 * * *) - Rebuilds the public CMS XML sitemap (public/sitemap-cms.xml) from the current published, public, indexable pages/posts and active taxonomy archives.
  • Run queued CMS Lighthouse tests (*/10 * * * *) - Processes a small batch of queued CMS Lighthouse/PageSpeed runs via the PageSpeed Insights API (never blocks publishing). Skips when Lighthouse is disabled.
  • Scan held CMS comments (AkbAI moderation) (*/2 * * * *) - Runs AkbAI/local moderation on the verdict-less pending CMS comment backlog and persists each verdict. The async path so a visitor submission is never blocked by AkbAI downtime.

Routes sampled

RouteTarget
content_adminContent_admin/index
content_admin/(:any)/(:any)/(:any)Content_admin/$1/$2/$3
content_admin/(:any)/(:any)Content_admin/$1/$2
content_admin/(:any)Content_admin/$1
cms/preview/(:any)Content_preview/show/$1
sitemap-cms.xmlContent_sitemap/index
feed-cms.xmlContent_feed/rss
feed-cms.jsonContent_feed/json_feed
cms/content/(:num)/viewContent/track_view/$1
cms/content/(:num)/commentContent/comment/$1
cms/content/(:num)/reactionContent/react/$1
blogContent/blog_index
blog/(:any)Content/post/$1
category/(:any)Content/category/$1
tag/(:any)Content/tag/$1
author/(:any)Content/author/$1
page/(:any)Content/page/$1
content/page/(:any)Content/page/$1
content/post/(:any)Content/post/$1
contentContent/index
2 additional route(s) omitted for readability.

README topics

  • Key architecture facts
  • Make it visible
  • Layout
  • Demo seeders

Operating Implications

  • Permission coverage is part of the module contract, so every workflow should be tested with a role-limited user and an administrator.
  • The module has migrations, so fresh installs and tenant databases need migration validation before go-live.
  • The module has API documentation or routes, so response examples and query filters should stay aligned with user-facing screens.
  • Scheduled jobs can change statuses, notifications, or summaries after users leave the screen; support should check cron status during troubleshooting.
  • Seeders exist for sample or starter data; operators should know whether seeded records are demo-only or operational defaults.

Known Risks from the Manifest

  • All 23 cms_* tables are GLOBAL/public content pinned to the PRIMARY database by Cms_base_model (every Cms_*_model opens the 'default' connection). Module migrations still run per-tenant via migrate:modules, but up()/down() are a no-op on tenant connections (guarded by is_tenant_loaded()); any empty cms_* tables in a tenant DB are unused - the canonical store is the primary DB (plan section 18.5). There is no 'primary_db_only' manifest flag in ERPat; the base-model pin is the enforcement mechanism.
  • Public POST endpoints (comment, reaction, view) require the native CodeIgniter CSRF token, which the public layout renders for AJAX. The module-owned End-User API (/v1/api/cms/*) is stateless JWT bearer-authenticated, so CSRF must NOT be enforced on that surface (like the rest of the EU/integration API).
  • Route overrides (homepage /, module index /community) are OFF by default (cms.route_overrides_enabled / cms.homepage_override_enabled / cms.module_overrides_enabled = 0). The existing system homepage and Community controller index remain the live fallback until an authorized user (content_routes_activate) activates an assignment to a PUBLISHED CMS page; every activation/rollback is audit-logged and reversible.
  • AkbAI comment safety (scan + optional reply) is OFF by default (cms.akbai_comment_scan_enabled / cms.akbai_comment_reply_enabled = 0; cms.comment_moderation_mode = advisory). Comment text is treated strictly as untrusted DATA by a fixed classifier prompt (prompt-injection defense, section 8.23.1); AkbAI downtime never blocks submission (local heuristic fallback / queue as pending).
  • Guest comment emails are never persisted in plaintext - only an HMAC-SHA256 hash (visitor_email_hash) is stored; guest bans key on an HMAC visitor_hash, never a bare IP.
  • THEMES: public CMS pages render through the active theme (cms.active_theme, default 'default') via CmsThemeService::render_page(), which returns FALSE (emitting nothing) on any missing/disabled/erroring theme so the controller falls back to the legacy content/public/* view - the public site can never blank or 500 because of a theme. Theme templates are developer-authored CODE (like component view.php); the admin edits only theme OPTION DATA (cms_theme_settings), never template code. Theme switch records the previous theme for one-click revert and is audit-logged.
  • MENUS: the top-bar/footer navigation is backend-managed (cms_menus/cms_menu_items, primary-DB only). module_page items render only when module_enabled(module_key) is true and core_page items only when the target route exists - failing items are silently dropped from the public menu (never a broken link) and flagged in the admin builder. External custom_url items are forced rel=noopener noreferrer; internal targets are validated against reserved/admin paths.
Was this guide helpful?

Report a content problem