Files
opensourcepos/app/Libraries/Plugins/BasePlugin.php
Ollama a9669ddf19 feat(plugins): Implement modular plugin system with self-registering events
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
2026-03-09 21:58:53 +01:00

98 lines
2.3 KiB
PHP

<?php
namespace App\Libraries\Plugins;
use App\Models\Plugin_config;
/**
* Base Plugin Class
*
* Abstract base class providing common plugin functionality.
* Plugins can extend this class to reduce boilerplate code.
*/
abstract class BasePlugin implements PluginInterface
{
protected Plugin_config $configModel;
public function __construct()
{
$this->configModel = new Plugin_config();
}
/**
* Default install implementation.
* Override in subclass for custom installation logic.
*/
public function install(): bool
{
return true;
}
/**
* Default uninstall implementation.
* Override in subclass for custom uninstallation logic.
*/
public function uninstall(): bool
{
return true;
}
/**
* Check if the plugin is enabled.
*/
public function isEnabled(): bool
{
$enabled = $this->configModel->get("{$this->getPluginId()}_enabled");
return $enabled === '1' || $enabled === 'true';
}
/**
* Get a plugin setting.
*/
protected function getSetting(string $key, mixed $default = null): mixed
{
$value = $this->configModel->get("{$this->getPluginId()}_{$key}");
return $value ?? $default;
}
/**
* Set a plugin setting.
*/
protected function setSetting(string $key, mixed $value): bool
{
$stringValue = is_array($value) || is_object($value)
? json_encode($value)
: (string)$value;
return $this->configModel->set("{$this->getPluginId()}_{$key}", $stringValue);
}
/**
* Get all plugin settings.
*/
public function getSettings(): array
{
return $this->configModel->getPluginSettings($this->getPluginId());
}
/**
* Save plugin settings.
*/
public function saveSettings(array $settings): bool
{
$prefixedSettings = [];
foreach ($settings as $key => $value) {
$prefixedSettings["{$this->getPluginId()}_{$key}"] = (string)$value;
}
return $this->configModel->batchSave($prefixedSettings);
}
/**
* Log a plugin-specific message.
*/
protected function log(string $level, string $message): void
{
log_message($level, "[Plugin:{$this->getPluginName()}] {$message}");
}
}