Commit Graph
24 Commits
Author SHA1 Message Date
objecttothis cc68b75b26 fix(plugins): block install completion until plugin migrations run
Previously, plugin migrations only ran once during PluginManager
initialization for already-enabled plugins, which caused the login
"latest version" check to report the system as up to date even when
plugin migrations were still pending. Newly enabled plugins also had
no path to run their migrations at enable time.

- Login controller: factor pending-migration check into
  isLatest determination, and explicitly run pending plugin
  migrations after core migrations complete
- PluginManager: remove implicit migration run from init(); add
  public hasPendingMigrations() and runPendingMigrations() so
  callers can check/trigger migrations explicitly
- PluginManager: extract getPendingMigrationFiles() helper shared
  by hasPendingMigrations() and per-plugin migration runner
- PluginManager: run pending migrations immediately when a plugin
  is enabled, instead of waiting for next request/init
- PluginManager: throw RuntimeException on missing migration class
  or failed migration instead of silently breaking the loop, so
  failures propagate to callers

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-10 12:26:51 +04:00
objecttothis 974ba4acc6 fix(plugins): rerun pending plugin migrations on every request
Session flag `plugin_migrations_ran` skipped migration checks after
first run per session, so newly added plugin migrations were not
applied until session reset/logout.

- app/Libraries/Plugins/PluginManager.php: remove session-based
  guard in runPendingMigrations(); migrations table check now runs
  every request, relying on existing per-migration tracking to
  avoid redundant work

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-09 13:55:44 +04:00
Travis Garrison 59aa7f1ec2 refactor(plugins): enforce plugin id naming convention and auto-cleanup on uninstall
- Add `idMatchesPluginConvention()` guard to `BasePlugin` — rejects
  module/permission ids that don't match `{plugin_id}` or `{plugin_id}_*`
- Add `unregisterPluginModules()` to `PluginManager` — called automatically
  on uninstall; removes all modules and sub-permissions by convention prefix
- Plugins no longer need to call `unregisterModule()` in `uninstall()`
- Update README to document enforced naming convention, auto-cleanup
  behavior, and corrected language key / file location guidance

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-29 17:48:51 +04:00
Travis Garrison 584d38426c feat(plugins): add uninstall confirmation modal and soft-delete uninstall
- Intercept uninstall action to show confirmation modal before AJAX call
- Change uninstall to soft-delete: set installed=0 instead of purging all config
- Add deleteAllNonControlForPlugin to preserve control rows on uninstall
- Add isPluginInstalled helper to PluginManager for installed state checks
- Fix isInstalled guard to treat installed=0 as not installed

Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
2026-07-07 17:54:18 +04:00
Travis Garrison bdb2ba5b51 Add table existence check in PluginManager before initializing migrations
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
2026-06-29 12:04:08 +04:00
objec 150cdfb2b8 Add plugin migration system
- Add `runPendingMigrations()` to `PluginManager` for executing plugin-specific migrations.
- Create `PluginMigrationModel` for managing plugin migration versions.
- Add migration for creating the `plugin_migrations` table to track migration states.

Signed-off-by: objec <objecttothis@gmail.com>
2026-06-26 16:19:04 +04:00
objec 139f754a07 Refactor manage plugin configuration and settings
- Add column to indicate control setting (installed, enabled).
- Add column to indicate plugin.
- Rework business logic to read the status properly.
- Renamed the migration to properly reflect which version it's released in.

Signed-off-by: objec <objecttothis@gmail.com>
2026-05-20 17:43:42 +04:00
objec cd91ac3ff3 Fix bugs
- Add missing `MailchimpPlugin.` prefix to lang() calls.
- Do not subscribe customer if consent is not true.
- Escape output in tabular_helper.php
- Removed testConnection() as unneeded code
- Fix activity count logic
- Whitelist Sort Column Headers for Plugins.php
- Store encrypted API key as base64 instead of raw binary to prevent truncation
- Rollback on batchSave partial failure.
- Remove dead code.
- Disable plugin before uninstalling it.
- Fix getPluginSettings() internal key leak
- Add action column to plugin headers function
- Automatically add grant to all admins in case person_id 1 is not active

Signed-off-by: objec <objecttothis@gmail.com>
2026-05-05 15:06:04 +04:00
objec fe331c34dd Mailchimp Bugfixes
- Update README.md to reflect information about routes
- Add registerAllNamespaces() function to correctly load plugin  namespaces
- center text in modal title
- Properly decrypt the api key
- Refactor getAllLists to getLists
- Naming simplification of strings when mailchimp_ is redundant or unnecessary
- Do not attempt to decrypt a plaintext api_key pasted into the form
- Register namespaces early on in system init

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-29 18:25:21 +04:00
objec 6630fb56f6 Fix language discovery bugs
- Remove unneeded keys from Config.php
- Remove unneeded lang() function override from BasePlugin.php
- Update README.md to reflect changes to language loading
- Correct language file string
- Correct lang() function calls to remove `$this->` from the call since we aren't overriding it anymore.
- Add code to correctly register namespace so that languages load.
- Fix plugin view render bug

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-29 16:31:14 +04:00
objec 2f48e0499f Plugin discovery bugfix
- Fix namespace typo causing plugin to not load
- Code cleanup

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-29 15:20:08 +04:00
objec cbabe1d56c Bugfix: Fix recursive view call
- Fix bug causing all plugin views to be rendered on every page.
- Simplify code
- Refactor manage.php view to use bootstrap tables

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-29 15:02:48 +04:00
objec 32997d48c0 Fix persistence problem with plugin registration.
- Move the PluginManager creation to a service.
- Move plugin discovery to creation.
- Create static discovery and namespaces variables in the PluginManager.php library
- Refactor persistent namespace declarations
- Refactor redundant code to private function.
- Remove whitespace
- Remove enable setting from MailchimpPlugin. That is handled by the PluginManager.php
- Update Events.php to call the pluginManager service
- Correct typo in enabled setting for BasePlugin to accurately reflect the database naming.

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-29 10:31:04 +04:00
objec 1a9e84bd37 Fix bugs preventing plugins from working
- Move Plugins controller and rename to reflect the rest of the code.
- Lazy load event registrations.
- Autoload classes so plugins are discovered.
- Remove TODO
- Remove unneeded use statement
- Correct typo in namespace of MailchimpConnector Library
- Add class names to autoload class map
- Move Plugin discovery to post_controller_constructor event

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-23 16:26:50 +04:00
objec c796b52c22 Correct mistakes in plugin code related to loading.
- Add plugin module to list of required admin modules.
- Don't trigger autoloader in plugin discovery.
- Delete plugins_config.php which is no longer needed for managing plugins.
- Remove references to plugins_configuration in config views.
- Correct the form submission URL path.

Signed-off-by: objec <objecttothis@gmail.com>
2026-04-23 12:42:34 +04:00
objec 196e87fa49 Resolve potential conflict with plugin settings installed and enabled
Signed-off-by: objec <objecttothis@gmail.com>
2026-04-14 11:56:17 +04:00
objec 84ea65b1bd Added check for plugin table before attempting to load plugins
Signed-off-by: objec <objecttothis@gmail.com>
2026-04-08 12:19:24 +04:00
objec acb3b18584 Load the namespace for the file so languages work in plugins
Signed-off-by: objec <objecttothis@gmail.com>
2026-04-02 17:07:27 +04:00
objec 19cdb76bb3 Removed whitespace in file
Signed-off-by: objec <objecttothis@gmail.com>
2026-04-02 16:26:32 +04:00
Ollama 0ea3ced674 fix: Rename Plugin_config methods to avoid conflict with CodeIgniter Model::set()
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
2026-03-24 08:07:18 +00:00
Ollama 896ed87797 fix: Address CodeRabbit AI review comments
- 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
2026-03-22 19:47:09 +00:00
Ollama eb264ad76d refactor: Address review comments - PSR-12 naming and plugin cleanup
- Rename Plugin_config to PluginConfig (PSR-12 class naming)
- Remove non-functioning CasposPlugin example
- Remove ExamplePlugin (MailchimpPlugin serves as example)
- Fix privacy issue: Don't log customer email in MailchimpPlugin
- Remove unnecessary PHPDocs
- Fix PSR-12 brace placement
2026-03-22 19:40:36 +00:00
Ollama bd8b4fa6c1 feat(plugins): Support self-contained plugin directories
- 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.
2026-03-09 21:58:53 +01:00
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