The PluginConfig class extends CodeIgniter\Model which has its own set() method
for query building. Renaming get()/set() to getValue()/setValue() avoids this conflict.
Also fixed:
- batchSave() to use setValue() instead of set()
- Updated all callers in PluginManager and BasePlugin to use renamed methods
- Move plugin discovery to pre_system in Events.php (allows events to be registered before they fire)
- Add plugin existence check in disablePlugin()
- Add is_subclass_of check before instantiating plugin classes
- Fix str_replace prefix removal in getPluginSettings using str_starts_with + substr
- Add down() migration to drop table on rollback
- Fix saveSettings to JSON-encode arrays/objects
- Update README to use MailchimpPlugin as reference implementation
- Remove CasposPlugin examples from documentation
- Consolidate duplicate documentation sections
- Move Internationalization section after Plugin Views
- Remove redundant Example Plugin Structure and View Hooks sections
- Fix PSR-12 brace style in plugin_helper.php
- Fix PSR-12 brace style in PluginInterface.php (remove unnecessary PHPdocs)
- Fix PSR-12 brace style in BasePlugin.php (remove unnecessary PHPdocs)
- Use log_message() instead of error_log() in migration
- Add IF NOT EXISTS to plugin_config table creation for resilience
- Convert snake_case to camelCase for class names throughout docs
- PluginManager now recursively scans app/Plugins/ to discover plugins
- Supports both single-file plugins (MyPlugin.php) and directory plugins (MyPlugin/MyPlugin.php)
- Plugins can contain their own Models, Controllers, Views, Libraries, Helpers
- Uses PSR-4 namespacing: App\Plugins\PluginName for files, App\Plugins\PluginName\Subdir for subdirectories
- Users can install plugins by simply dropping a folder into app/Plugins/
- Updated README with comprehensive documentation on both plugin formats
This makes plugin installation much easier - just drop the plugin folder and it works.
This implements a clean plugin architecture based on PR #4255 discussion:
Core Components:
- PluginInterface: Standard contract all plugins must implement
- BasePlugin: Abstract class with common functionality
- PluginManager: Discovers and loads plugins from app/Plugins/
- Plugin_config: Model for plugin settings storage
Architecture:
- Each plugin registers its own event listeners via registerEvents()
- No hardcoded plugin dependencies in core Events.php
- Generic event triggers (item_sale, item_change, etc.) remain in core code
- Plugins can be enabled/disabled via database settings
- Clean separation: plugin orchestrators vs MVC components
Example Implementations:
- ExamplePlugin: Simple plugin demonstrating event logging
- MailchimpPlugin: Integration with Mailchimp for customer sync
Admin UI:
- Plugin management controller at Controllers/Plugins/Manage.php
- Plugin management view at Views/plugins/manage.php
Database:
- ospos_plugin_config table for plugin settings (key-value store)
- Migration creates table with timestamps
Documentation:
- Comprehensive README with architecture patterns
- Simple vs complex plugin examples
- MVC directory structure guidance