Module Research Notes
Evidence gathered from the current module files before writing the user guide pages.
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
ContentContent_adminContent_api- pages, page, posts, post, categories, tags, comments, mediaContent_euapi- posts, post, page, comments, recommendations, postComment, addReaction, removeReactionContent_feedContent_previewContent_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
| Route | Target |
|---|---|
content_admin | Content_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.xml | Content_sitemap/index |
feed-cms.xml | Content_feed/rss |
feed-cms.json | Content_feed/json_feed |
cms/content/(:num)/view | Content/track_view/$1 |
cms/content/(:num)/comment | Content/comment/$1 |
cms/content/(:num)/reaction | Content/react/$1 |
blog | Content/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 |
content | Content/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.