|
| 1 | +<h1 align="center">laravel-install-wizard</h1> |
| 2 | + |
| 3 | +<p align="center"> |
| 4 | + A minimal, modern, multilingual Laravel installation wizard.<br /> |
| 5 | + shadcn-style UI · light / dark / system theme · 10 languages · zero CDN runtime deps. |
| 6 | +</p> |
| 7 | + |
| 8 | +<p align="center"> |
| 9 | + <a href="https://packagist.org/packages/nativecodein/laravel-install-wizard"><img src="https://img.shields.io/packagist/v/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="Latest Version on Packagist" /></a> |
| 10 | + <a href="https://packagist.org/packages/nativecodein/laravel-install-wizard"><img src="https://img.shields.io/packagist/dt/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="Total Downloads" /></a> |
| 11 | + <a href="https://packagist.org/packages/nativecodein/laravel-install-wizard"><img src="https://img.shields.io/packagist/php-v/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="PHP Version" /></a> |
| 12 | + <a href="https://github.com/nativecodein/laravel-install-wizard/actions"><img src="https://img.shields.io/github/actions/workflow/status/nativecodein/laravel-install-wizard/tests.yml?branch=main&style=flat-square&label=tests" alt="Tests" /></a> |
| 13 | + <a href="LICENSE"><img src="https://img.shields.io/packagist/l/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="License" /></a> |
| 14 | +</p> |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +When a fresh Laravel app has not yet been installed, `laravel-install-wizard` gently redirects every route to a clean web-based installer. The user names the app, configures the environment and database, sees PHP requirement and folder permission checks, then clicks **Install**. A `.installed` lock file is written and the wizard never appears again. |
| 19 | + |
| 20 | +## Table of contents |
| 21 | + |
| 22 | +- [Highlights](#highlights) |
| 23 | +- [Screenshots](#screenshots) |
| 24 | +- [Requirements](#requirements) |
| 25 | +- [Installation](#installation) |
| 26 | +- [Quick start](#quick-start) |
| 27 | +- [Configuration](#configuration) |
| 28 | +- [Multilingual support](#multilingual-support) |
| 29 | +- [Theming](#theming) |
| 30 | +- [Customizing views and assets](#customizing-views-and-assets) |
| 31 | +- [Resetting installation](#resetting-installation) |
| 32 | +- [Security](#security) |
| 33 | +- [Testing](#testing) |
| 34 | +- [Contributing](#contributing) |
| 35 | +- [Versioning](#versioning) |
| 36 | +- [Credits](#credits) |
| 37 | +- [License](#license) |
| 38 | + |
| 39 | +## Highlights |
| 40 | + |
| 41 | +- **Multi-step wizard** — Welcome → Environment → Database → Requirements → Permissions → Install |
| 42 | +- **Dynamic branding** — enter `NativeCode` and the installer becomes the *NativeCode Installer* everywhere |
| 43 | +- **Live database test** — MySQL, PostgreSQL, SQLite, SQL Server, validated before continuing |
| 44 | +- **Safe `.env` writer** — preserves comments, leaves unrelated keys alone, validates key format |
| 45 | +- **10 languages out of the box** — English, Spanish, French, German, Portuguese, Italian, Japanese, Chinese, Arabic (RTL), Hindi |
| 46 | +- **Light / Dark / System theme** — `localStorage` persistence, OS-preference reactive, no FOUC |
| 47 | +- **shadcn-style UI** — HSL CSS variables, Outfit font, accessible menus, keyboard nav |
| 48 | +- **Zero CDN runtime deps** — all CSS, JS and confetti inlined; only Google Fonts for Outfit |
| 49 | +- **Production-ready** — works without JavaScript via progressive enhancement |
| 50 | +- **Auto-discovered** — drop in via Composer, no service-provider wiring required |
| 51 | + |
| 52 | +## Screenshots |
| 53 | + |
| 54 | +> Add screenshots here once the package is hosted. Suggested shots: |
| 55 | +> `docs/welcome-light.png`, `docs/database-dark.png`, `docs/complete-rtl.png`. |
| 56 | +
|
| 57 | +``` |
| 58 | +[ welcome — light ] [ database — dark ] [ complete — confetti ] |
| 59 | +``` |
| 60 | + |
| 61 | +## Requirements |
| 62 | + |
| 63 | +- PHP 8.1, 8.2, 8.3 or 8.4 |
| 64 | +- Laravel 10, 11 or 12 |
| 65 | + |
| 66 | +## Installation |
| 67 | + |
| 68 | +```bash |
| 69 | +composer require nativecodein/laravel-install-wizard |
| 70 | +``` |
| 71 | + |
| 72 | +The service provider is auto-registered. On first request, since `storage/.installed` doesn't exist yet, every route redirects to `/install`. |
| 73 | + |
| 74 | +### Publishing files (optional) |
| 75 | + |
| 76 | +```bash |
| 77 | +# everything |
| 78 | +php artisan vendor:publish --tag=installwizard |
| 79 | + |
| 80 | +# or individually |
| 81 | +php artisan vendor:publish --tag=installwizard-config |
| 82 | +php artisan vendor:publish --tag=installwizard-views |
| 83 | +php artisan vendor:publish --tag=installwizard-lang |
| 84 | +php artisan vendor:publish --tag=installwizard-assets |
| 85 | +``` |
| 86 | + |
| 87 | +## Quick start |
| 88 | + |
| 89 | +1. Install via Composer. |
| 90 | +2. Open any route in your Laravel app — you'll be redirected to `/install`. |
| 91 | +3. Enter your application name (e.g. `NativeCode`). |
| 92 | +4. Fill in environment, database, watch the requirement and permission checks pass. |
| 93 | +5. Click **Install NativeCode**. The package writes `.env`, generates `APP_KEY`, clears caches, creates `storage/.installed`. |
| 94 | +6. Confetti fires. You're sent back to the route you originally requested. |
| 95 | +7. Future visits never see the wizard again. |
| 96 | + |
| 97 | +## Configuration |
| 98 | + |
| 99 | +After publishing the config, all behavior lives in `config/installwizard.php`: |
| 100 | + |
| 101 | +| Key | Default | Description | |
| 102 | +|---|---|---| |
| 103 | +| `installed_file` | `storage_path('.installed')` | Lock file that gates the wizard | |
| 104 | +| `route_prefix` | `install` | URL prefix for wizard routes | |
| 105 | +| `auto_apply_middleware` | `true` | Append the gating middleware to the `web` group automatically | |
| 106 | +| `redirect_after_install` | `/` | Fallback target after install if no intended URL | |
| 107 | +| `required_extensions` | 12 standard exts | PHP extensions checked in step 4 | |
| 108 | +| `writable_paths` | storage + bootstrap/cache | Paths verified in step 5 | |
| 109 | +| `final.run_migrations` | `false` | Run `migrate --force` at the end | |
| 110 | +| `final.run_seeders` | `false` | Run `db:seed --force` at the end | |
| 111 | +| `final.generate_key` | `true` | Generate `APP_KEY` if missing | |
| 112 | +| `final.clear_caches` | `true` | Clear config/route/view/cache stores | |
| 113 | +| `locales` | 10 locales | Languages offered in the switcher | |
| 114 | +| `rtl_locales` | `['ar','he','fa','ur']` | Forced right-to-left layout | |
| 115 | +| `default_theme` | `system` | Initial theme: `light`, `dark`, or `system` | |
| 116 | + |
| 117 | +## Multilingual support |
| 118 | + |
| 119 | +Ten locales ship out of the box. A globe button in the header opens a language picker; the choice persists in the user's session. |
| 120 | + |
| 121 | +| Code | Language | Code | Language | |
| 122 | +|---|---|---|---| |
| 123 | +| `en` | English | `it` | Italiano | |
| 124 | +| `es` | Español | `ja` | 日本語 | |
| 125 | +| `fr` | Français | `zh` | 中文 | |
| 126 | +| `de` | Deutsch | `ar` | العربية (RTL) | |
| 127 | +| `pt` | Português | `hi` | हिन्दी | |
| 128 | + |
| 129 | +### Adding a language |
| 130 | + |
| 131 | +```bash |
| 132 | +php artisan vendor:publish --tag=installwizard-lang |
| 133 | +``` |
| 134 | + |
| 135 | +Create `lang/vendor/installwizard/{locale}/messages.php`, copy keys from `en/messages.php`, translate, then declare it in config: |
| 136 | + |
| 137 | +```php |
| 138 | +// config/installwizard.php |
| 139 | +'locales' => [ |
| 140 | + 'en' => 'English', |
| 141 | + 'tr' => 'Türkçe', // new |
| 142 | +], |
| 143 | +'rtl_locales' => ['ar', 'he', 'fa', 'ur'], // add new RTL locales here |
| 144 | +``` |
| 145 | + |
| 146 | +RTL locales render with `dir="rtl"` automatically. |
| 147 | + |
| 148 | +## Theming |
| 149 | + |
| 150 | +The theme toggle in the header offers three modes: |
| 151 | + |
| 152 | +- **Light** — `<html>` has no `dark` class |
| 153 | +- **Dark** — `<html class="dark">` |
| 154 | +- **System** — follows `prefers-color-scheme` and reacts live to OS changes |
| 155 | + |
| 156 | +The choice is stored in `localStorage` under `installwizard.theme`. An inline `<script>` in `<head>` applies the class before paint, so there is no flash. |
| 157 | + |
| 158 | +### Customizing colors |
| 159 | + |
| 160 | +Publish the views, then edit the CSS variables at the top of `resources/views/vendor/installwizard/layout.blade.php`: |
| 161 | + |
| 162 | +```css |
| 163 | +:root { |
| 164 | + --primary: 240 5.9% 10%; |
| 165 | + --background: 0 0% 100%; |
| 166 | + /* … */ |
| 167 | +} |
| 168 | +.dark { |
| 169 | + --primary: 0 0% 98%; |
| 170 | + /* … */ |
| 171 | +} |
| 172 | +``` |
| 173 | + |
| 174 | +All variables follow [shadcn/ui](https://ui.shadcn.com) conventions — HSL component triplets consumed with `hsl(var(--token))`. |
| 175 | + |
| 176 | +## Customizing views and assets |
| 177 | + |
| 178 | +```bash |
| 179 | +php artisan vendor:publish --tag=installwizard-views |
| 180 | +``` |
| 181 | + |
| 182 | +Views land in `resources/views/vendor/installwizard/` and override the package versions automatically. Edit them however you like — the package will pick up your changes immediately. |
| 183 | + |
| 184 | +Assets are inlined into the layout by default, so publishing CSS/JS is only needed if you want to bundle the wizard into your own Vite pipeline. |
| 185 | + |
| 186 | +## Resetting installation |
| 187 | + |
| 188 | +```bash |
| 189 | +# wipe the lock file — wizard appears on the next request |
| 190 | +rm storage/.installed |
| 191 | +``` |
| 192 | + |
| 193 | +Or programmatically: |
| 194 | + |
| 195 | +```php |
| 196 | +app(\Nativecodein\LaravelInstallWizard\Services\Installer::class)->removeLockFile(); |
| 197 | +``` |
| 198 | + |
| 199 | +## Security |
| 200 | + |
| 201 | +- The `EnvWriter` validates env keys against `/^[A-Z_][A-Z0-9_]*$/` and rejects anything else. |
| 202 | +- Existing comments and unrelated `.env` values are preserved during writes. |
| 203 | +- All forms are CSRF-protected through the `web` middleware group. |
| 204 | +- The locale switcher validates against the configured allow-list before persisting. |
| 205 | +- The gating middleware only stores intended URLs for GET requests (never AJAX/XHR), preventing redirect loops. |
| 206 | +- API requests get a 503 JSON response instead of a redirect, preventing fetch/axios redirect loops. |
| 207 | +- No external CDN dependencies at runtime — all CSS, JS and confetti are inlined. |
| 208 | + |
| 209 | +If you discover a security vulnerability, please email **security@nativecode.in** rather than opening a public issue. |
| 210 | + |
| 211 | +## Testing |
| 212 | + |
| 213 | +```bash |
| 214 | +composer install |
| 215 | +vendor/bin/phpunit |
| 216 | +``` |
| 217 | + |
| 218 | +The suite uses [Orchestra Testbench](https://github.com/orchestral/testbench) and covers: |
| 219 | + |
| 220 | +- redirects when not installed / access granted when installed |
| 221 | +- creation of the `.installed` lock file |
| 222 | +- safe `.env` writing (comment & key preservation) |
| 223 | +- database tester (success & failure paths) |
| 224 | +- requirement checker (extensions, writable paths) |
| 225 | +- middleware redirect-loop avoidance |
| 226 | +- locale persistence, RTL detection, per-locale translation rendering |
| 227 | + |
| 228 | +## Contributing |
| 229 | + |
| 230 | +Contributions are welcome. To get started: |
| 231 | + |
| 232 | +```bash |
| 233 | +git clone https://github.com/nativecodein/laravel-install-wizard.git |
| 234 | +cd laravel-install-wizard |
| 235 | +composer install |
| 236 | +vendor/bin/phpunit |
| 237 | +``` |
| 238 | + |
| 239 | +### Submitting changes |
| 240 | + |
| 241 | +1. Fork the repo and create a feature branch: `git checkout -b feature/your-thing` |
| 242 | +2. Write or update tests for your change. |
| 243 | +3. Ensure `vendor/bin/phpunit` passes locally. |
| 244 | +4. Open a pull request describing the *why* (motivation) and the *what* (change summary). |
| 245 | + |
| 246 | +### Reporting issues |
| 247 | + |
| 248 | +When opening a bug report, please include: |
| 249 | + |
| 250 | +- Laravel and PHP versions (`php artisan --version`, `php -v`) |
| 251 | +- The contents of `config/installwizard.php` if you've customized it |
| 252 | +- Browser and OS for UI bugs |
| 253 | +- A minimal reproduction repo if possible |
| 254 | + |
| 255 | +### Translations |
| 256 | + |
| 257 | +To contribute a new language, copy `src/resources/lang/en/messages.php`, translate, and submit a PR. Native speakers reviewing existing translations are also very welcome. |
| 258 | + |
| 259 | +### Code style |
| 260 | + |
| 261 | +This project follows PSR-12. Keep controllers thin, services pure, and Blade views accessible. Avoid introducing runtime CDN dependencies — everything that ships in the layout is inlined deliberately. |
| 262 | + |
| 263 | +## Versioning |
| 264 | + |
| 265 | +This package follows [Semantic Versioning](https://semver.org). Breaking changes only ship in major releases. |
| 266 | + |
| 267 | +## Credits |
| 268 | + |
| 269 | +- [NativeCode](https://nativecode.in) — original author and maintainer |
| 270 | +- [Laravel](https://laravel.com) — the framework this package extends |
| 271 | +- [shadcn/ui](https://ui.shadcn.com) — design tokens and component vocabulary that inspired the UI |
| 272 | +- [Outfit](https://fonts.google.com/specimen/Outfit) — typeface |
| 273 | +- All [contributors](https://github.com/nativecodein/laravel-install-wizard/contributors) |
| 274 | + |
| 275 | +## License |
| 276 | + |
| 277 | +The MIT License (MIT). Please see the [LICENSE](LICENSE) file for more information. |
| 278 | + |
| 279 | +--- |
| 280 | + |
| 281 | +<p align="center"> |
| 282 | + Contributed by <a href="https://nativecode.in"><strong>NativeCode</strong></a><br /> |
| 283 | + <a href="https://nativecode.in">https://nativecode.in</a> |
| 284 | +</p> |
0 commit comments