PolyCMS Architecture Overview
Last updated on May 16, 2026 2:03 AM
MVC Architecture
PolyCMS follows strict Model-View-Controller architecture built on CodeIgniter — the same framework powering Perfex CRM. This ensures seamless integration with the CRM's existing codebase and conventions.
File Structure
modules/polycms/
├── assets/ # CSS, JS, images for admin & frontend
├── controllers/ # MVC Controllers
│ ├── Posts.php # Post CRUD operations
│ ├── Pages.php # Page management
│ ├── Categories.php # Category management
│ ├── Tags.php # Tag management
│ ├── Media.php # Media Library operations
│ ├── Comments.php # Comment moderation
│ ├── Menus.php # Menu builder
│ ├── Themes.php # Theme management
│ ├── Plugins.php # Plugin management
│ ├── Settings.php # CMS settings
│ ├── Tools.php # Backup, Import/Export
│ ├── Frontend.php # Public-facing routes & rendering
│ └── Dashboard.php # CMS Dashboard
├── helpers/ # Helper functions
│ ├── polycms_blog_helper.php
│ ├── polycms_seo_helper.php
│ └── polycms_hook_helper.php
├── language/ # 16 language packs
├── libraries/ # Service classes
│ ├── ThemeLoader.php # Theme template resolution
│ ├── PluginManager.php # Plugin lifecycle management
│ └── ShortcodeParser.php
├── models/ # Database models
│ ├── Blog_post_model.php
│ ├── Blog_category_model.php
│ └── ... (one per table group)
├── plugins/ # Bundled plugins (5 included)
├── themes/ # Bundled themes
├── views/ # Admin & frontend view templates
├── migrations/ # Database migration files
├── documentations/ # Included documentation
├── install.php # Database schema creation
├── uninstall.php # Safe deactivation (preserves data)
└── polycms.php # Module entry point & hook registration
Database Schema
PolyCMS creates 16 dedicated tables, all prefixed with your Perfex CRM table prefix + blog_:
| Group | Tables |
|---|---|
| Content | blog_posts, blog_pages, blog_page_meta |
| Taxonomy | blog_categories, blog_tags, blog_post_categories, blog_post_tags, blog_post_meta |
| Engagement | blog_comments |
| Navigation | blog_menus, blog_menu_items, blog_widgets |
| Extensions | blog_plugins, blog_plugin_options, blog_themes, blog_theme_options |
| Configuration | blog_settings, blog_permalink_settings |
All tables use proper foreign key constraints and indexes for optimal query performance. CMS data is completely isolated from CRM client data.
Request Lifecycle
Admin Requests
- Perfex CRM routes request to PolyCMS controller.
- Controller validates
staff_can()permissions. - Controller calls Model for database operations.
- Model returns data via CodeIgniter Active Record.
- Controller loads admin View with data.
Frontend Requests
- Dynamic routing system matches URL against permalink patterns.
Frontend.phpcontroller determines content type (post, page, category, tag, search, archive).- Hooks fire:
polycms_frontend_init,polycms_head. ThemeLoaderresolves template hierarchy → selects appropriate theme template.- Template renders with data, widgets, and shortcodes processed.
- Hooks fire:
polycms_footer.
Plugin System Architecture
Plugins are loaded by the PluginManager during module initialization:
- Scan
plugins/directory forplugin.jsonmanifests. - Check activation status in
blog_pluginstable. - Load active plugin main files.
- Plugins register hooks via
polycms_add_action()andpolycms_add_filter(). - Hooks fire at appropriate lifecycle points during request processing.
Theme System Architecture
The ThemeLoader handles template resolution:
- Check active theme in
blog_themestable. - Determine content type from current request.
- Walk template hierarchy:
single.php→category.php→tag.php→page.php→index.php. - Load first matching template file from active theme directory.
- Pass content data, widgets, and theme options to template scope.
Security Architecture
- Permission Layer — All admin actions gated by
staff_can('polycms', ...). - XSS Protection — HTMLPurifier sanitizes all rich-text content.
- SQL Protection — CodeIgniter Active Record/Query Builder prevents injection.
- File Protection —
polycms_validate_file_pathprevents directory traversal. - Rate Limiting — IP-based cache limiter on public endpoints.
- BASEPATH Guard — Every PHP file includes
defined('BASEPATH') or exit().
Related Documentation
- Hooks & Filters Reference — Complete hook API documentation.
- Building a Custom Plugin — Plugin development guide with sample code.
- Building a Custom Theme — Theme development guide with template hierarchy.
- Template Tags & Helpers — Available helper functions for themes and plugins.