Nazmart Plugin System
The Nazmart plugin system provides a structured, WordPress-inspired extension mechanism built natively in PHP and Laravel. Plugins let you add features — new admin pages, hooks into commerce flows, custom API routes, tenant-scoped settings, and more — without modifying the Nazmart core.
Plugin Discovery
The platform scans two directories for plugins at boot time:
Modules/— first-party and marketplace modules (Laravel module-style)plugins/— third-party plugins installed via ZIP or CLI
Each plugin must contain a plugin.json manifest in its root directory. Any directory lacking this file is ignored by the plugin scanner.
Context: Landlord vs Tenant vs Both
Every plugin declares a type field that controls in which runtime context it boots:
| Type | Boots in | Use case |
|---|---|---|
landlord | Central platform admin only | Platform-wide reports, billing integrations |
tenant | Tenant shop subdomains only | Loyalty programs, custom shipping, storefront widgets |
both | Both contexts | Shared utilities, analytics, SEO tools |
Boot Process
On each request the PluginManager determines which plugins to activate:
- Reads
storage/app/modules_statuses.jsonfor globally enabled/disabled state. - Queries the
plugin_tenant_overridestable to apply per-tenant allow/deny rules. - Filters by context (landlord vs tenant subdomain).
- Checks
requiresdependencies — missing dependencies cause the plugin to be skipped. - Instantiates each plugin class and calls
boot()wrapped in a try/catch.
Getting Started
Scaffold a New Plugin
The fastest way to start is the Artisan scaffold command:
# Creates plugins/acme-seo/ with plugin.json + boilerplate class
php artisan plugin:create acme-seo
Install from ZIP
Marketplace and purchased plugins are distributed as ZIP archives:
php artisan plugin:install /path/to/acme-seo-1.0.0.zip
List All Plugins
php artisan plugin:list
Minimal Plugin Structure
plugins/acme-seo/
├── plugin.json # manifest — required
├── src/
│ └── AcmeSeoPlugin.php # main class — required
├── resources/
│ ├── views/ # Blade templates
│ └── lang/ # translation files
├── database/
│ └── migrations/ # optional migrations
└── routes/
└── web.php # optional Laravel routes
💡 The scaffold command generates all these directories and stubs automatically. You only need to fill in the logic.
plugin.json Schema Reference
Every plugin must have a plugin.json at its root. All fields are case-sensitive.
// plugin.json — complete example with all fields
{
"id": "acme-seo", // required — kebab-case, globally unique
"name": "Acme SEO", // required — human-readable display name
"version": "1.0.0", // required — semver
"description": "SEO meta & sitemap", // optional
"type": "tenant", // required — landlord | tenant | both
"pricing": "free", // required — free | paid
"min_platform_version": "2.5.0", // required — semver, checked against core
"main": "src/AcmeSeoPlugin.php", // required — relative path to main class
"requires": ["shipping-plugin"], // optional — array of plugin IDs
"author": "Acme Corp", // optional
"update_server": "https://updates.acme.com", // optional — for auto-updates
"purchase_url": "https://acme.com/buy" // optional — shown in admin for paid
}
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Required | Kebab-case unique identifier. Used as the canonical key throughout the system. |
name | string | Required | Human-readable display name shown in admin. |
version | semver | Required | Current plugin version. Compared against update_server for update detection. |
description | string | Optional | Short description shown in plugin list. |
type | enum | Required | landlord, tenant, or both. |
pricing | enum | Required | free or paid. Paid plugins require license validation. |
min_platform_version | semver | Required | Minimum Nazmart core version. Plugin skipped if core is older. |
main | path | Required | Relative path to the PHP file containing your main class. |
requires | array | Optional | Plugin IDs that must be active before this plugin boots. |
author | string | Optional | Author or company name. |
update_server | URL | Optional | Base URL of your update server. See §13 for the contract. |
purchase_url | URL | Optional | Shown as a "Buy" link in the plugin admin when unlicensed. |

