Skip to main content

Configuration

Addons use multiple configuration files to define metadata, settings, and navigation. This guide covers all configuration options.

Addon Metadata (Settings/config.php)

The Settings/config.php file defines how your addon appears in the admin panel:

<?php

$setting = [
// Display Information
'name' => 'Email Validator',
'vendor' => 'Your Company',
'type' => 'Integration',
'description' => 'Validate and verify email addresses in real-time.',
'logo' => 'https://yoursite.com/addons/emailvalidator/images/logo.png',
'slider' => [
'https://yoursite.com/addons/emailvalidator/images/slide1.png',
'https://yoursite.com/addons/emailvalidator/images/slide2.png',
],
'read_more' => 'https://yoursite.com/addons/emailvalidator',

// Version Control
'version' => '1.2.0',
'new_version_url' => 'https://yoursite.com/addon/version.json',

// Routing
'route' => 'email-validator',
'install_dir' => basename(dirname(__DIR__)), // Auto-detect from directory name

// Licensing
'license_type' => 'marketplace',
'native_addon_name' => '', // Required when license_type is 'native'
'license_key' => '',
];

Field Reference

FieldTypeDescription
namestringDisplay name in addon manager
vendorstringDeveloper/company name
typestringCategory: Integration, Feature, Utility, etc.
descriptionstringDescription shown on the addons page
logostringURL to the addon logo image
sliderarrayArray of image URLs for the addon detail slider
read_morestringURL to the addon's detail/marketing page
versionstringCurrent version (semantic versioning)
new_version_urlstringURL returning JSON with latest version
routestringBase URL prefix for addon routes
install_dirstringDirectory name under /Addons (use basename(dirname(__DIR__)) to auto-detect)
license_typestringLicense model (see below)
native_addon_namestringAddon name on Mumara's license server (required for native type)
license_keystringLicense key if pre-configured

License Types

TypeDescription
nativeVerified against Mumara's main license server
marketplaceVerified via Mumara Marketplace API
remoteCustom verification against your own server
freeNo license required

Version Checking

For automatic update checking, your new_version_url should return:

{
"version": "1.3.0",
"changelog": "Bug fixes and performance improvements",
"release_date": "2024-01-15"
}

Application Config (Config/config.php)

The Config/config.php file contains runtime configuration that can be published and overridden:

<?php

return [
'name' => 'Email Validator',

// API Settings
'api' => [
'endpoint' => env('EMAIL_VALIDATOR_API_URL', 'https://api.example.com'),
'timeout' => env('EMAIL_VALIDATOR_TIMEOUT', 30),
'retry_attempts' => 3,
],

// Feature Flags
'features' => [
'real_time_validation' => true,
'batch_processing' => true,
'webhook_notifications' => false,
],

// Cache Settings
'cache' => [
'enabled' => true,
'ttl' => 3600, // seconds
'prefix' => 'email_validator_',
],

// Default Settings
'defaults' => [
'validation_level' => 'standard',
'max_batch_size' => 1000,
],
];

Accessing Configuration

// Get single value
$endpoint = config('emailvalidator.api.endpoint');

// Get with default
$timeout = config('emailvalidator.api.timeout', 60);

// Get entire section
$apiConfig = config('emailvalidator.api');

// Check if exists
if (config()->has('emailvalidator.features.webhooks')) {
// ...
}

Publishing Configuration

Users can publish and customize config:

php artisan vendor:publish --tag=emailvalidator-config

This copies your config to config/emailvalidator.php where users can modify it.

Register publishing in your service provider:

public function boot(): void
{
$this->publishes([
module_path($this->moduleName, 'Config/config.php')
=> config_path($this->moduleNameLower . '.php'),
], 'config');
}

Environment Variables

Use environment variables for sensitive or environment-specific values:

// Config/config.php
'api_key' => env('EMAIL_VALIDATOR_API_KEY'),
'debug' => env('EMAIL_VALIDATOR_DEBUG', false),

Users add to their .env:

EMAIL_VALIDATOR_API_KEY=your-api-key-here
EMAIL_VALIDATOR_DEBUG=true

The menu.json file defines sidebar navigation entries:

Simple Menu Item

[
{
"title": "Email Validator",
"icon": "<i class='kt-menu__link-icon flaticon-email'></i>",
"url": "email-validator",
"hidden": false,
"hasChild": false,
"childrens": []
}
]
[
{
"title": "Email Validator",
"icon": "<i class='kt-menu__link-icon flaticon-email'></i>",
"url": "#",
"hidden": false,
"hasChild": true,
"childrens": [
{
"title": "Dashboard",
"icon": "<i class='menu-bullet menu-bullet-dot'><span></span></i>",
"url": "email-validator",
"hidden": false
},
{
"title": "Validate Emails",
"icon": "<i class='menu-bullet menu-bullet-dot'><span></span></i>",
"url": "email-validator/validate",
"hidden": false
},
{
"title": "History",
"icon": "<i class='menu-bullet menu-bullet-dot'><span></span></i>",
"url": "email-validator/history",
"hidden": false
},
{
"title": "Settings",
"icon": "<i class='menu-bullet menu-bullet-dot'><span></span></i>",
"url": "email-validator/settings",
"hidden": false
}
]
}
]
FieldTypeDescription
titlestringDisplay text
iconstringHTML icon element
urlstringRoute path (relative) or "#" for parent
hiddenbooleanHide from menu if true
hasChildbooleanHas submenu items
childrensarraySubmenu items

Common Icons

<!-- Flaticon (Metronic theme) -->
<i class='kt-menu__link-icon flaticon-email'></i>
<i class='kt-menu__link-icon flaticon-settings'></i>
<i class='kt-menu__link-icon flaticon-analytics'></i>
<i class='kt-menu__link-icon flaticon-users'></i>
<i class='kt-menu__link-icon flaticon-list'></i>

<!-- Font Awesome -->
<i class='kt-menu__link-icon fas fa-envelope'></i>
<i class='kt-menu__link-icon fas fa-cog'></i>
<i class='kt-menu__link-icon fas fa-chart-bar'></i>

<!-- Submenu bullet -->
<i class='menu-bullet menu-bullet-dot'><span></span></i>
<i class='menu-bullet menu-bullet-line'><span></span></i>

Module Manifest (module.json)

The module.json file is the addon's manifest:

{
"name": "EmailValidator",
"alias": "emailvalidator",
"description": "Real-time email validation and verification",
"keywords": ["email", "validation", "verification", "hygiene"],
"priority": 0,
"providers": [
"Addons\\EmailValidator\\Providers\\EmailValidatorServiceProvider",
"Addons\\EmailValidator\\Providers\\EventServiceProvider"
],
"files": [
"Helpers/functions.php"
],
"requires": []
}

Field Reference

FieldTypeDescription
namestringAddon name (PascalCase, must match directory)
aliasstringLowercase identifier for views/routes
descriptionstringBrief description
keywordsarraySearch keywords
priorityintegerLoad order (lower = earlier)
providersarrayService providers to register
filesarrayPHP files to autoload
requiresarrayDependencies on other addons

Dependencies

If your addon depends on another addon:

{
"requires": [
"OtherAddon"
]
}

The system ensures dependencies are loaded first.

Composer Dependencies (composer.json)

Define PHP package dependencies:

{
"name": "yourcompany/emailvalidator",
"description": "Email validation addon for Mumara Campaigns",
"type": "library",
"require": {
"guzzlehttp/guzzle": "^7.0",
"egulias/email-validator": "^4.0"
},
"autoload": {
"psr-4": {
"Addons\\EmailValidator\\": ""
}
}
}

Addon composer.json files are automatically merged with the main application's dependencies via wikimedia/composer-merge-plugin. After modifying, run from the project root:

composer update

Asset Compilation (webpack.mix.js)

Configure Laravel Mix to compile source assets from Resources/assets/ into your addon's public/ directory. This keeps assets self-contained and accessible via the symlink:

const mix = require('laravel-mix');

// Compile into your addon's own public/ directory (recommended)
mix.js(__dirname + '/Resources/assets/js/app.js', __dirname + '/public/js/addon.js')
.sass(__dirname + '/Resources/assets/sass/app.scss', __dirname + '/public/css/addon.css');

if (mix.inProduction()) {
mix.version();
}

The compiled files will be accessible at /Addons/YourAddonName/js/addon.js and /Addons/YourAddonName/css/addon.css via the symlink.

Build assets:

cd Addons/EmailValidator
npm install
npm run dev # Development
npm run production # Production with versioning

Storing Addon Settings

For user-configurable settings, store in the database:

Create Settings Model

// Models/AddonSetting.php
namespace Addons\EmailValidator\Models;

use Illuminate\Database\Eloquent\Model;

class AddonSetting extends Model
{
protected $table = 'email_validator_settings';

protected $fillable = ['key', 'value', 'user_id'];

protected $casts = [
'value' => 'json',
];

public static function get(string $key, $default = null, ?int $userId = null)
{
$query = static::where('key', $key);

if ($userId) {
$query->where('user_id', $userId);
}

$setting = $query->first();

return $setting ? $setting->value : $default;
}

public static function set(string $key, $value, ?int $userId = null): void
{
static::updateOrCreate(
['key' => $key, 'user_id' => $userId],
['value' => $value]
);
}
}

Create Migration

Schema::create('email_validator_settings', function (Blueprint $table) {
$table->id();
$table->string('key');
$table->json('value')->nullable();
$table->foreignId('user_id')->nullable()->constrained()->onDelete('cascade');
$table->timestamps();

$table->unique(['key', 'user_id']);
});

Usage

use Addons\EmailValidator\Models\AddonSetting;

// Get setting
$apiKey = AddonSetting::get('api_key');

// Get with default
$batchSize = AddonSetting::get('batch_size', 100);

// Get user-specific setting
$userLimit = AddonSetting::get('daily_limit', 1000, auth()->id());

// Set setting
AddonSetting::set('api_key', 'your-key');

// Set user-specific setting
AddonSetting::set('daily_limit', 500, auth()->id());