PHPackages                             softcortex/magic-installer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. softcortex/magic-installer

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

softcortex/magic-installer
==========================

Professional WordPress-like installer wizard for Laravel applications with Envato purchase code verification. Perfect for CodeCanyon products and commercial Laravel applications.

v1.4.5(3mo ago)065MITPHPPHP ^8.2CI passing

Since Dec 29Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/ouhssini/installer)[ Packagist](https://packagist.org/packages/softcortex/magic-installer)[ Docs](https://github.com/softcortex/magic-installer)[ RSS](/packages/softcortex-magic-installer/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (13)Versions (31)Used By (0)

Laravel Envato Installer Wizard
===============================

[](#laravel-envato-installer-wizard)

[![Latest Version on Packagist](https://camo.githubusercontent.com/4b6db5a99535d267d0f9abba0ede71d332042f21328955e5bfac1405cd1f8cb1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6674636f727465782f6d616769632d696e7374616c6c65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/softcortex/magic-installer)[![Total Downloads](https://camo.githubusercontent.com/9964393b26eb75336ac1ed0eb9b543fe4aa1e3b3a7a1d08da4ae4893b8b13f34/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736f6674636f727465782f6d616769632d696e7374616c6c65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/softcortex/magic-installer)[![License](https://camo.githubusercontent.com/d5364082b14b487a8e3f567ae0ba30c91b95539a2926db4567b7eba205c51e30/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f736f6674636f727465782f6d616769632d696e7374616c6c65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/softcortex/magic-installer)

A professional WordPress-like installer wizard for Laravel 11+ applications with built-in Envato purchase code verification. Perfect for CodeCanyon products and commercial Laravel applications.

✨ Features
----------

[](#-features)

- 🎨 **Beautiful UI** - Clean, modern interface with TailwindCSS
- 🔐 **Envato Integration** - Real Envato API v3 purchase code verification with dev mode
- ✅ **Requirements Check** - Automatic PHP version, extensions, and permissions validation
- 🗄️ **Database Setup** - Interactive database configuration with real-time connection testing
- 🔄 **Auto Migration** - Automatic database migration during installation
- 👤 **Admin Creation** - Secure admin account setup with smart role assignment (supports Spatie Permission)
- 🔒 **Security First** - Stateless forms, secure session handling, password hashing
- 🚀 **One-Click Install** - Complete installation in 7 steps
- 🔓 **Recovery Command** - Unlock installer if needed
- 🧪 **Property Testing** - 39,000+ assertions with property-based tests
- 🔧 **Step Validation** - Prevents accessing steps out of order
- 💾 **File-First Storage** - Works before database setup

📋 Requirements
--------------

[](#-requirements)

- PHP 8.2 or higher
- Laravel 11 or 12
- Composer
- Writable `storage/app` directory
- MySQL/PostgreSQL/SQLite database

📦 Installation
--------------

[](#-installation)

Install the package via Composer:

```
composer require softcortex/magic-installer
```

> **Note**: The installer uses file-based storage (`storage/app/.installed` and `storage/app/installer-settings.json`) and does NOT require database setup before running. This means it works immediately after `composer require` without any database configuration.

### Publish Assets (Recommended Before Installation)

[](#publish-assets-recommended-before-installation)

**For developers distributing this as part of their product:**

1. **Publish the `.env.example` file** (includes pre-configured Envato settings):

```
php artisan vendor:publish --tag="installer-env"
```

2. **Edit the published `.env.example`** in your project root and add your Envato credentials:

```
LICENSE_ENABLED=true
LICENSE_DEV_MODE=false
ENVATO_PERSONAL_TOKEN=your-token-here
ENVATO_ITEM_ID=12345678
```

3. The installer will use **your customized `.env.example`** as the template when creating `.env` during installation.

> **Why publish `.env.example`?** The installer prioritizes the project's `.env.example` over the package's version. This allows you to pre-configure Envato tokens and other settings for your end users.

**Optional: Publish other assets**

Publish the configuration file:

```
php artisan vendor:publish --tag="installer-config"
```

Optionally, publish the views for customization:

```
php artisan vendor:publish --tag="installer-views"
```

Optionally, publish the settings table migration (if you want to customize it before installation):

```
php artisan vendor:publish --tag="installer-migrations"
```

> **Note**: Publishing the migration is optional. The installer automatically creates the `settings` table during Step 4 (Database configuration) using Laravel's Schema builder.

**Or publish everything at once:**

```
php artisan vendor:publish --provider="SoftCortex\Installer\InstallerServiceProvider"
```

⚙️ Configuration
----------------

[](#️-configuration)

### Storage

[](#storage)

The installer uses file-based storage to avoid database dependency issues:

- **Installation Status**: `storage/app/.installed`
- **Settings**: `storage/app/installer-settings.json`

This approach ensures the installer works before database configuration, eliminating the chicken-and-egg problem.

### 1. Envato Personal Token Setup

[](#1-envato-personal-token-setup)

To enable Envato purchase code verification:

1. Visit
2. Create a token with these permissions:
    - ✅ View and search Envato sites
    - ✅ View the user's account username
3. Add to your `.env` file:

```
LICENSE_ENABLED=true
LICENSE_DEV_MODE=false
ENVATO_PERSONAL_TOKEN=your-personal-token-here
ENVATO_ITEM_ID=12345678  # Optional: Your CodeCanyon item ID
```

#### Development Mode

[](#development-mode)

For development/testing without real Envato API calls:

```
LICENSE_ENABLED=true
LICENSE_DEV_MODE=true
```

Then use the test purchase code: `dev-test-code-12345678-1234`

#### Skip License Step

[](#skip-license-step)

To completely skip license verification:

```
LICENSE_ENABLED=false
```

### 2. Middleware Setup

[](#2-middleware-setup)

The installer automatically registers:

1. **Custom `installer` middleware group** (no EncryptCookies/StartSession) - Allows installation before `APP_KEY` exists
2. **Global `EnsureInstalled` middleware** - Redirects all routes to `/install` until installation completes

**Key Architecture:**

- Installer routes use custom middleware without session/cookie encryption
- All forms are stateless (no CSRF tokens, no `old()` helpers)
- Database drivers (session, cache, queue) switch to `database` automatically after installation

No manual middleware configuration required - works out of the box!

### 3. Configuration Options

[](#3-configuration-options)

Customize `config/installer.php`:

```
return [
    'product' => [
        'name' => env('APP_NAME', 'Laravel Application'),
        'version' => '1.0.0',
    ],

    'requirements' => [
        'php' => '8.2',
        'extensions' => ['pdo', 'openssl', 'mbstring', 'tokenizer', 'xml', 'ctype', 'json', 'bcmath'],
        'directories' => ['storage/framework', 'storage/logs', 'bootstrap/cache'],
    ],

    'license' => [
        'enabled' => env('LICENSE_ENABLED', true),
        'dev_mode' => env('LICENSE_DEV_MODE', false),
        'envato_personal_token' => env('ENVATO_PERSONAL_TOKEN', ''),
        'envato_item_id' => env('ENVATO_ITEM_ID', null),
    ],

    'admin' => [
        'role' => 'admin',
        'create_role_if_missing' => true,
    ],

    'routes' => [
        'prefix' => 'install',
        'middleware' => 'installer',  // Custom middleware group
        'redirect_after_install' => 'dashboard',
    ],
];
```

🚀 Usage
-------

[](#-usage)

### Installation Wizard

[](#installation-wizard)

1. Navigate to `/install` in your browser
2. Follow the 7-step wizard:
    - **Step 1: Welcome** - Introduction and getting started
    - **Step 2: App Config** - Set application name, URL, timezone, locale (creates `.env` + `APP_KEY`)
    - **Step 3: Requirements** - PHP version, extensions, directory permissions check
    - **Step 4: Database** - Database configuration, connection test, **runs migrations**
    - **Step 5: License** - Purchase code verification (optional, can be disabled)
    - **Step 6: Admin** - Create administrator account with role assignment
    - **Step 7: Finalize** - Switch to database drivers, sync data, lock installer

**Step Validation:**

- Each step validates that previous steps are completed
- Attempting to access `/install/admin` before database setup redirects to `/install/database`
- Ensures proper installation sequence and prevents errors

### Real-Time Validation

[](#real-time-validation)

- **Database Test Connection** - Verify credentials before saving
- **License Verification** - Validate purchase code against Envato API before continuing
- **Requirements Check** - Live status of PHP version, extensions, and permissions

### Purchase Code Format

[](#purchase-code-format)

Envato purchase codes must be in UUID format:

```
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

```

The installer:

- ✅ Validates against Envato API in real-time
- ✅ Stores only SHA-256 hash (never the actual code)
- ✅ Retrieves license info: item name, buyer, dates, support expiry

### Unlock Installer

[](#unlock-installer)

Re-run the installer if needed:

```
php artisan installer:unlock
```

Force unlock without confirmation:

```
php artisan installer:unlock --force
```

🎨 Customization
---------------

[](#-customization)

### Views

[](#views)

Publish and modify views:

```
php artisan vendor:publish --tag="installer-views"
```

Views location: `resources/views/vendor/installer/`

### Routes

[](#routes)

Change the installer URL prefix in `config/installer.php`:

```
'routes' => [
    'prefix' => 'setup',  // URL becomes /setup
],
```

### Styling

[](#styling)

The installer uses TailwindCSS. Customize by:

1. Publishing views
2. Modifying Tailwind classes
3. Adding custom CSS to the layout

🔒 Security
----------

[](#-security)

### Best Practices

[](#best-practices)

- ✅ Always use HTTPS in production
- ✅ Keep Envato Personal Token secure (never commit to Git)
- ✅ Use strong admin passwords
- ✅ Run `installer:unlock` only when necessary

### Data Storage

[](#data-storage)

**File-based storage:**

- ✅ Installation status in `storage/app/.installed`
- ✅ Settings in `storage/app/installer-settings.json`
- ✅ SHA-256 hash of purchase code
- ✅ License metadata (item name, buyer, dates)

**Never stored:**

- ❌ Envato Personal Token
- ❌ Plain text purchase codes

🏗️ Architecture
---------------

[](#️-architecture)

### Stateless Forms

[](#stateless-forms)

The installer uses **stateless forms** before `APP_KEY` generation:

- No CSRF tokens on installer routes
- No `old()` helpers or `$errors` variables
- Controllers return views directly with error messages
- Form values preserved via explicit `$credentials` or `$formData` variables

### File-First Storage

[](#file-first-storage)

Installation state stored in files, **not database**:

- `storage/app/.installed` - Installation lock file
- `storage/app/installer-settings.json` - Step progress and settings
- Database sync happens in Step 7 (Finalize) to `settings` table

**Why?** Avoids chicken-and-egg problem - installer must work before database exists!

### Migration Timing

[](#migration-timing)

**Migrations run in Step 4 (Database)**, not Step 7:

- Creates `settings` table with `category` and `changeable` columns
- Creates `users` table before Step 6 (Admin creation)
- Uses Laravel Schema builder for database-agnostic compatibility

### Smart Admin Role Assignment

[](#smart-admin-role-assignment)

Automatically detects and assigns admin role:

1. Checks for `role` or `roles` column in `users` table
2. Detects Spatie Permission package (`HasRoles` trait)
3. Creates role if missing (when `create_role_if_missing=true`)
4. Assigns appropriate role to admin user

🐛 Troubleshooting
-----------------

[](#-troubleshooting)

IssueSolution"MissingAppKeyException"Normal on first access - installer creates `.env` and generates `APP_KEY` in Step 2"Envato Personal Token not configured"Add `ENVATO_PERSONAL_TOKEN` to `.env` or set `LICENSE_ENABLED=false`"Invalid purchase code format"Use UUID format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`"License verification failed: 401"Token expired - create new one at [build.envato.com](https://build.envato.com/create-token/)"Purchase code not found"Verify code is correct in Envato or enable dev modeDatabase connection failedCheck credentials, server status, firewall, ensure database exists"Table 'users' doesn't exist"Migrations run in Step 4 - ensure you complete database step before admin creationPermission errorsEnsure `storage/app` directory is writable: `chmod -R 775 storage`Form inputs lost after errorFixed in v1.2.0+ - forms now preserve values on validation failureCan't access step out of orderBy design - each step validates previous steps are completedStep validation not workingClear browser cache, ensure you're not bypassing middleware🧪 Testing
---------

[](#-testing)

Run the test suite:

```
composer test
```

Run specific test types:

```
vendor/bin/pest --group=property  # Property-based tests
vendor/bin/pest --group=unit      # Unit tests
```

📚 API Reference
---------------

[](#-api-reference)

### LicenseService

[](#licenseservice)

```
use SoftCortex\Installer\Services\LicenseService;

$service = app(LicenseService::class);
$result = $service->verify('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx');

if ($result->isValid()) {
    echo $result->itemName;
    echo $result->buyerName;
    echo $result->licenseType; // 'regular' or 'extended'
}
```

### InstallerService

[](#installerservice)

```
use SoftCortex\Installer\Services\InstallerService;

$installer = app(InstallerService::class);

if ($installer->isInstalled()) {
    // App is installed
}

$installer->setSetting('key', 'value');
$value = $installer->getSetting('key', 'default');
```

📝 Changelog
-----------

[](#-changelog)

See [CHANGELOG.md](CHANGELOG.md) for recent changes.

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

🔐 Security
----------

[](#-security-1)

Report security vulnerabilities via [our security policy](../../security/policy).

👥 Credits
---------

[](#-credits)

- [Ouhssini](https://github.com/ouhssini)
- [All Contributors](../../contributors)

📄 License
---------

[](#-license)

MIT License. See [LICENSE.md](LICENSE.md) for details.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance78

Regular maintenance activity

Popularity10

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

30

Last Release

115d ago

PHP version history (2 changes)v1.0.0PHP ^8.4

v1.0.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/a633d8cdc6a0d7ba53e48893d604fbd1c7bf9281016497335c2d40896cb3a632?d=identicon)[ouhssini](/maintainers/ouhssini)

---

Top Contributors

[![ouhssini](https://avatars.githubusercontent.com/u/19697159?v=4)](https://github.com/ouhssini "ouhssini (61 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

laravelinstallerlaravel-packagewizardenvatocodecanyoninstallationpurchase-codelicense-verificationsetup-wizard

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/softcortex-magic-installer/health.svg)

```
[![Health](https://phpackages.com/badges/softcortex-magic-installer/health.svg)](https://phpackages.com/packages/softcortex-magic-installer)
```

###  Alternatives

[spatie/laravel-data

Create unified resources and data transfer objects

1.7k28.9M626](/packages/spatie-laravel-data)[hirethunk/verbs

An event sourcing package that feels nice.

513162.9k6](/packages/hirethunk-verbs)[worksome/exchange

Check Exchange Rates for any currency in Laravel.

123544.7k](/packages/worksome-exchange)[ralphjsmit/livewire-urls

Get the previous and current url in Livewire.

82270.3k4](/packages/ralphjsmit-livewire-urls)[hydrat/filament-table-layout-toggle

Filament plugin adding a toggle button to tables, allowing user to switch between Grid and Table layouts.

6292.3k1](/packages/hydrat-filament-table-layout-toggle)[ralphjsmit/laravel-helpers

A package containing handy helpers for your Laravel-application.

13704.6k2](/packages/ralphjsmit-laravel-helpers)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
