Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Plugin Laravel Package

catchadmin/plugin

Plugin manager for the CatchAdmin admin framework built on Laravel, providing a modular system to package, install, enable, and remove admin extensions. Handles plugin discovery, configuration, and lifecycle hooks so custom backend features can be added or dropped without touching core code.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer from your CatchAdmin application root:

composer require catchadmin/plugin

Then publish and run its migrations so the plugin registry table exists:

php artisan vendor:publish --provider="CatchAdmin\Plugin\PluginServiceProvider"
php artisan migrate

The plugin manager registers a route group under the admin panel (typically /admin/plugins). Log in as an admin, and you should see a plugin list with install/enable/disable/uninstall actions. This UI is the primary surface — it drives the lifecycle operations that the package performs programmatically.

Where to look first:

  1. config/plugin.php (or config/catch.php depending on the merged config) — this defines the plugin root path, the manifest filename, and the namespace prefix. Almost every customization decision lives here.
  2. The plugin directory on disk (commonly plugins/ at the project root or modules/ under app/) — each subfolder is a plugin.
  3. The package's Plugin model / repository — it tracks name, title, version, status, and installed_at.

First use case: Scaffold a trivial "hello world" plugin, enable it from the admin UI, and confirm a route it registers resolves. This validates the entire pipeline (autoload, provider boot, route registration) before you invest in a real feature. If you have an artisan generator (many versions ship php artisan plugin:make Name), use it — hand-rolling the folder structure is where most first attempts fail.

Implementation Patterns

Manifest-driven plugins. Each plugin is defined by a manifest (usually plugin.json or info.php) that declares the plugin name, title, description, version, author, and — critically — the namespace and service provider. The manager reads this to render the list and to decide what class to boot. Treat the manifest as the source of truth; the database row is a cache of its status.

Service provider as the integration point. A plugin typically contains a Providers/PluginServiceProvider that registers routes, views, translations, and migrations. Follow the standard Laravel package conventions inside it:

public function boot()
{
    $this->loadRoutesFrom(__DIR__.'/../routes/admin.php');
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'myplugin');
    $this->loadMigrationsFrom(__DIR__.'/../database/migrations');
    $this->publishes([...], 'myplugin-assets');
}

The plugin manager decides whether to register this provider based on the plugin's enabled status, so never assume your boot() runs — always guard side effects (migrations, config writes) behind install/enable hooks rather than boot().

Lifecycle hooks. The manager exposes install / enable / disable / uninstall events. Common pattern: put data-initialization logic (seed permissions, create menu entries, publish assets) in an install() method or an install-time migration rather than in a service provider. Enabling a plugin is usually cheap (flip a status and re-register providers); installing is the expensive, one-time operation.

Menu and permission integration. In CatchAdmin-flavored plugins, you'll usually register admin menu items and permission slugs on install. Do this by inserting rows via the CatchAdmin menu model inside your install routine, and delete them on uninstall. If you skip cleanup on uninstall, the admin menu accumulates dead links — a very common complaint.

Composer autoload for plugin namespaces. If plugins live outside app/, you need the composer autoloader to know about them:

"autoload": {
  "psr-4": { "Plugin\\": "plugins/" }
}

Then composer dump-autoload after creating a new plugin. Some setups rely on the plugin manager dynamically adding autoloaders at runtime — if so, don't rely on that in tests or console commands where the manager may not boot.

Version-gated plugins. If you ship plugins that must match the host app version, read the manifest's require/version field and refuse install when the running CatchAdmin version doesn't satisfy it. Better to fail fast at install than to boot a broken provider.

Gotchas and Tips

  • Cache is the number-one debugging trap. Enabling or disabling a plugin often only takes effect after php artisan cache:clear and sometimes php artisan config:clear. If a plugin "won't show up," clear caches before touching code.
  • composer dump-autoload after every new plugin folder. Namespace-not-found errors on a fresh plugin are almost always an autoloader problem, not a manager bug.
  • Provider ordering. Plugin providers may load before your app's own providers depending on how the manager hooks in. If a plugin needs your app's config or bindings, resolve them lazily inside boot(), not at the top of the provider file.
  • Migrations run in install order, not dependency order. If plugin B depends on plugin A's tables, document that A must be installed first. There's typically no dependency resolver.
  • Uninstall is destructive and inconsistent across versions. Verify whether uninstall drops tables, removes the directory, or does neither. Back up before testing uninstall; several versions only flip the status row and leave files behind.
  • Zero stars / low maturity signal. Expect sparse documentation, breaking changes between minor versions, and code you'll need to read directly. Pin the version in composer.json and vendor-review the PluginManager class before relying on lifecycle guarantees in production.
  • Extension points: the manager is usually a thin service you can swap via container binding. If you need custom install logic (e.g., remote plugin registry), bind your own implementation of the manager's installer/loader interfaces in an app service provider rather than editing vendor code.
  • Logging: install/enable failures are often swallowed. Wrap your own install hooks in try/catch and log to a dedicated channel so failures don't disappear behind a generic UI toast.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums