Introduce a plugin framework and management UI: adds Plugin Manager controller, Plugin_awards controller, Plugin_manager and Cloudlog_hooks libraries, Plugins_model, migration (268) to create the plugins table, and views for plugin manager and award pages. Integrates hooks into Logbook_model (qso.filter.before_save, qso.action.after_save, qso.action.after_edit), updates header to show award plugin entries and a Plugin Manager menu link, and bumps migration_version to 268. Also adds .gitignore rules, plugin index placeholder, docs and example plugin packages. The Plugin Manager supports uploading/installing ZIP packages, safe extraction, manifest validation, enable/disable/delete actions, and CSRF protection.
9.1 KiB
Cloudlog Plugin Manager Guide (Developer Reference)
This guide is a detailed technical reference for Cloudlog's Plugin Manager.
It focuses on what developers can do, how the manager works internally, and how to build plugin packages that install and upgrade cleanly.
1. Scope and Audience
This document is for developers who:
- Build Cloudlog plugins.
- Maintain plugin zip releases.
- Need predictable install/upgrade behavior.
- Need to troubleshoot plugin install or runtime issues.
For writing award-specific plugin logic, also see:
For system-level architecture overview, see:
2. Plugin Manager Capabilities
The Plugin Manager currently supports:
- Uploading and installing plugin zip packages.
- Metadata registration in the
pluginsdatabase table. - Enabling/disabling plugins.
- Deleting plugins (files on disk + registry record).
- In-place upgrade when a zip is uploaded with an existing plugin slug.
- Upgrade backup and rollback on failure.
- Validation checks for archive safety and manifest structure.
Current implementation entry points:
- Controller: application/controllers/Plugins.php
- Runtime library: application/libraries/Plugin_manager.php
- Data model: application/models/Plugins_model.php
- Admin UI view: application/views/plugins/index.php
3. Data Model and Persistence
Migration:
Table: plugins
Key fields:
plugin_slug: unique plugin identity.plugin_name,plugin_version,plugin_description.plugin_status:enabledordisabled.plugin_manifest: stored JSON manifest snapshot.installed_at,updated_at.
Important behavior:
- The DB record is the plugin registry.
- On listing, manager attempts to read manifest from disk first, then falls back to DB snapshot.
upsert_pluginpreserves enabled status during upgrades.
4. Plugin Package Requirements
A valid plugin zip must:
- Contain
manifest.jsoneither at zip root or inside a single top-level folder. - Include a valid
slugin manifest matching pattern^[a-z0-9_-]+$. - Include code files referenced by
entryandclassmanifest fields (or defaults).
Minimum recommended package:
my-plugin/
manifest.json
Plugin.php
README.md
Reference examples:
5. Upload and Install Workflow (What Happens)
When an admin uploads a plugin zip in Plugin Manager:
- CSRF token is validated.
- Zip upload is accepted only for
.zipextension and configured limits. - Archive is inspected for unsafe paths.
- Archive is extracted to a temp directory.
manifest.jsonis located and parsed.- Manifest and slug are validated.
- Plugin files are copied to
application/plugins/<slug>/. - Plugin metadata is upserted into DB.
- Plugin remains disabled by default (unless existing plugin was already enabled and upgraded).
Key code paths:
Plugins::upload()in application/controllers/Plugins.phpPlugin_manager::install_from_zip()in application/libraries/Plugin_manager.php
6. Upgrade-in-Place Behavior
If uploaded plugin slug already exists on disk:
- Existing plugin directory is moved to backup.
- New files are copied in.
- DB metadata is updated.
- Backup is deleted on success.
If file copy or DB update fails:
- New files are removed.
- Backup is restored.
Result:
- Reduced risk of partial updates.
- Safer iterative plugin release workflow.
7. Security and Safety Checks
The manager applies multiple protection layers.
7.1 Authorization
- Plugin Manager UI/actions require admin authorization (
authorize(99)).
7.2 CSRF on Admin Actions
Custom session token is required for:
- Upload
- Enable
- Disable
- Delete
7.3 Archive Path Validation
Installer rejects zip entries containing:
- Path traversal (
../) - Absolute paths
- Drive-root style paths
This protects against writing outside plugin directory.
7.4 Manifest Validation
Installer validates:
- JSON parseability
- Valid slug pattern
- Award menu method shape (warning if declaration looks invalid/missing)
7.5 Runtime Resilience
- Hook and award-render exceptions are caught/logged.
- Core QSO workflows continue if plugin execution fails.
8. Enable/Disable Semantics
Enable/disable toggles update plugin_status in DB.
Effects:
- Disabled plugins do not run hooks.
- Disabled plugins do not appear in dynamic Awards plugin entries.
- Files remain on disk; only runtime activation changes.
Methods:
Plugin_manager::set_enabled()Plugins::enable()andPlugins::disable()
9. Award Menu Integration via Plugin Manager
Plugin Manager provides menu entry discovery for enabled plugins through:
Plugin_manager::get_award_menu_entries()
Manifest award_menu fields interpreted:
title: required for menu inclusion.route: defaults toplugin_awards/view/<slug>.icon: defaults tofas fa-award.order: sort key (then title).
Rendered from header template:
Award route controller:
10. Delete/Uninstall Behavior
Delete in Plugin Manager performs two actions:
- Removes the plugin directory from
application/plugins/<slug>/. - Removes the plugin record from the
pluginstable.
Important notes:
- Delete is an admin-only action and CSRF protected.
- If file removal fails, metadata is not removed.
- If metadata removal fails, an error is returned and action is reported as failed.
11. Disk Layout and Git Workflow
Installed plugins live under:
application/plugins/<slug>/
Repository ignore strategy should keep folder scaffold while ignoring installed plugin contents.
Current .gitignore behavior:
- Ignores all under
application/plugins/* - Re-includes
application/plugins/index.html
This allows:
- Folder existence after clone.
- Local plugin installations without git noise during pull/rebase.
12. Developer Packaging Checklist
Before shipping a plugin zip:
- Validate
manifest.jsonsyntax. - Confirm
slugis stable and lowercase. - Confirm
entryfile exists in package. - Confirm class name matches manifest
class. - Confirm
award_menu.methodexists if used. - Increment version for each release.
- Test upgrade path by installing old version then uploading new version.
13. Common Errors and Fixes
Error: "manifest.json was not found"
Cause:
- Incorrect zip structure.
Fix:
- Place
manifest.jsonat root or within one top-level folder.
Error: "manifest.json is invalid JSON"
Cause:
- Trailing comma or malformed JSON.
Fix:
- Validate with a JSON linter before zipping.
Error: "Invalid plugin slug"
Cause:
- Slug has spaces/uppercase/special characters.
Fix:
- Use lowercase letters, numbers,
_,-.
Warning about award_menu.method
Cause:
- Method declared but missing in entry file.
Fix:
- Implement method or correct spelling in manifest.
Plugin installs but does not appear in Awards
Cause:
- Plugin disabled or missing valid
award_menublock.
Fix:
- Enable plugin and verify
award_menu.title+ method declaration.
Upgrade appears not applied
Cause:
- Same version uploaded or old package re-zipped accidentally.
Fix:
- Bump version, verify zip contents, reinstall.
14. Operational Best Practices
- Keep plugin slugs permanent.
- Treat manifest as contract/API for manager.
- Keep plugin code self-contained inside plugin folder.
- Avoid side effects in constructors.
- Log meaningful errors with plugin slug context.
- Keep upgrade releases atomic and small.
15. What Plugin Manager Does Not Do (Yet)
Current known limitations:
- No plugin signature verification.
- No marketplace/remote catalog.
- No capability/permission prompt model.
- No staged/canary rollout.
These are potential future-phase enhancements.
16. Useful Source References
- Plugin Manager controller:
- Plugin manager runtime logic:
- Plugin data access model:
- Plugin awards route:
- Hook runtime:
- Plugin Manager UI:
- Phase 1 architecture document: