Xgenious/ docs
Products
Get support

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:

TypeBoots inUse case
landlordCentral platform admin onlyPlatform-wide reports, billing integrations
tenantTenant shop subdomains onlyLoyalty programs, custom shipping, storefront widgets
bothBoth contextsShared utilities, analytics, SEO tools

Boot Process

On each request the PluginManager determines which plugins to activate:

  1. Reads storage/app/modules_statuses.json for globally enabled/disabled state.
  2. Queries the plugin_tenant_overrides table to apply per-tenant allow/deny rules.
  3. Filters by context (landlord vs tenant subdomain).
  4. Checks requires dependencies — missing dependencies cause the plugin to be skipped.
  5. 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
Warning

💡 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
}
FieldTypeRequiredDescription
idstringRequiredKebab-case unique identifier. Used as the canonical key throughout the system.
namestringRequiredHuman-readable display name shown in admin.
versionsemverRequiredCurrent plugin version. Compared against update_server for update detection.
descriptionstringOptionalShort description shown in plugin list.
typeenumRequiredlandlord, tenant, or both.
pricingenumRequiredfree or paid. Paid plugins require license validation.
min_platform_versionsemverRequiredMinimum Nazmart core version. Plugin skipped if core is older.
mainpathRequiredRelative path to the PHP file containing your main class.
requiresarrayOptionalPlugin IDs that must be active before this plugin boots.
authorstringOptionalAuthor or company name.
update_serverURLOptionalBase URL of your update server. See §13 for the contract.
purchase_urlURLOptionalShown as a "Buy" link in the plugin admin when unlicensed.
Still stuck?
Our support team is ready to help you get set up.
Get support