PHP code example of innodite / laravel-module-maker
1. Go to this page and download the library: Download innodite/laravel-module-maker library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
innodite / laravel-module-maker example snippets
// Controlador — uso de renderModule()
class CentralUserController extends Controller
{
use RendersInertiaModule;
public function index(): JsonResponse
{
$users = $this->service->paginate();
return response()->json($users);
}
public function create(): \Inertia\Response
{
return $this->renderModule('CentralUserCreate');
// Retorna la vista Inertia — sin datos de negocio
}
}
// Bloque generado para: User (Contexto: App Central)
Route::prefix('central')->name('central.')->middleware(['web','auth'])->group(function () {
Route::prefix('users')->name('users.')->group(function () {
Route::get('/', [CentralUserController::class, 'index'])->name('index');
Route::get('/create', [CentralUserController::class, 'create'])->name('create');
Route::post('/', [CentralUserController::class, 'store'])->name('store');
Route::get('/{id}', [CentralUserController::class, 'show'])->name('show');
Route::get('/{id}/edit', [CentralUserController::class, 'edit'])->name('edit');
Route::put('/{id}', [CentralUserController::class, 'update'])->name('update');
Route::delete('/{id}', [CentralUserController::class, 'destroy'])->name('destroy');
});
});
// {{CENTRAL_ROUTES_END}}
// Bloque generado para: Invoice (Contexto: Shared — panel central)
Route::prefix('central/shared')->name('central.shared.')->middleware(['web','auth'])->group(function () {
Route::prefix('invoices')->name('invoices.')->group(function () {
Route::get('/', [SharedInvoiceController::class, 'index'])->name('index');
Route::get('/create', [SharedInvoiceController::class, 'create'])->name('create');
Route::post('/', [SharedInvoiceController::class, 'store'])->name('store');
Route::get('/{id}', [SharedInvoiceController::class, 'show'])->name('show');
Route::get('/{id}/edit', [SharedInvoiceController::class, 'edit'])->name('edit');
Route::put('/{id}', [SharedInvoiceController::class, 'update'])->name('update');
Route::delete('/{id}', [SharedInvoiceController::class, 'destroy'])->name('destroy');
});
});
// {{CENTRAL_ROUTES_END}}
// Bloque generado para: Invoice (Contexto: Shared — panel tenant)
Route::prefix('tenant/shared')->name('tenant.shared.')->middleware(['web','auth'])->group(function () {
Route::prefix('invoices')->name('invoices.')->group(function () {
Route::get('/', [SharedInvoiceController::class, 'index'])->name('index');
Route::get('/create', [SharedInvoiceController::class, 'create'])->name('create');
Route::post('/', [SharedInvoiceController::class, 'store'])->name('store');
Route::get('/{id}', [SharedInvoiceController::class, 'show'])->name('show');
Route::get('/{id}/edit', [SharedInvoiceController::class, 'edit'])->name('edit');
Route::put('/{id}', [SharedInvoiceController::class, 'update'])->name('update');
Route::delete('/{id}', [SharedInvoiceController::class, 'destroy'])->name('destroy');
});
});
// {{TENANT_SHARED_ROUTES_END}}
// Bloque generado para: Role (Contexto: Tenant Shared)
Route::middleware(['web','auth'])->group(function () {
Route::prefix('roles')->name('roles.')->group(function () {
Route::get('/', [TenantSharedRoleController::class, 'index'])->name('index');
Route::get('/create', [TenantSharedRoleController::class, 'create'])->name('create');
Route::post('/', [TenantSharedRoleController::class, 'store'])->name('store');
Route::get('/{id}', [TenantSharedRoleController::class, 'show'])->name('show');
Route::get('/{id}/edit', [TenantSharedRoleController::class, 'edit'])->name('edit');
Route::put('/{id}', [TenantSharedRoleController::class, 'update'])->name('update');
Route::delete('/{id}', [TenantSharedRoleController::class, 'destroy'])->name('destroy');
});
});
// {{TENANT_SHARED_ROUTES_END}}
// Bloque generado para: Product (Contexto: INNODITE)
Route::prefix('innodite')->name('innodite.')->middleware(['web','auth','tenant-auth'])->group(function () {
Route::prefix('products')->name('products.')->group(function () {
Route::get('/', [TenantINNODITEProductController::class, 'index'])->name('index');
Route::get('/create', [TenantINNODITEProductController::class, 'create'])->name('create');
Route::post('/', [TenantINNODITEProductController::class, 'store'])->name('store');
Route::get('/{id}', [TenantINNODITEProductController::class, 'show'])->name('show');
Route::get('/{id}/edit', [TenantINNODITEProductController::class, 'edit'])->name('edit');
Route::put('/{id}', [TenantINNODITEProductController::class, 'update'])->name('update');
Route::delete('/{id}', [TenantINNODITEProductController::class, 'destroy'])->name('destroy');
});
});
// {{TENANT_INNODITE_ROUTES_END}}
->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('web', [
\Innodite\LaravelModuleMaker\Middleware\InnoditeContextBridge::class,
]);
})
Route::middleware('innodite.bridge')->group(fn() => ...);
use Innodite\LaravelModuleMaker\Contracts\InnoditeUserPermissions;
class User extends Authenticatable implements InnoditeUserPermissions
{
public function getInnoditePermissions(): array
{
return $this->permissions->pluck('name')->toArray();
}
}
// Al final del archivo, por contexto central y shared-web:
// {{CENTRAL_ROUTES_END}}
// Por contexto tenant_shared y shared-tenant:
// {{TENANT_SHARED_ROUTES_END}}
// Por cada tenant específico (uno por tenant, basado en class_prefix):
// {{TENANT_INNODITE_ROUTES_END}}
// {{TENANT_ACME_ROUTES_END}}
// Acceso programático al log
ModuleAuditor::readLog(); // devuelve array de entradas
ModuleAuditor::logPath(); // devuelve ruta absoluta al archivo de log
bash
# Configuración make-module.php
php artisan vendor:publish --tag=module-maker-config
# Stubs PHP y Vue para personalización (4 carpetas contextuales)
php artisan vendor:publish --tag=module-maker-stubs
# contexts.json de ejemplo
php artisan vendor:publish --tag=module-maker-contexts
# Composables Vue 3 (useModuleContext, usePermissions)
php artisan vendor:publish --tag=module-maker-frontend
Modules/UserManagement/
├── Models/Central/Role/CentralRole.php
├── Http/Controllers/Central/Role/CentralRoleController.php
├── Http/Requests/Central/Role/CentralRoleStoreRequest.php
├── Http/Requests/Central/Role/CentralRoleUpdateRequest.php
├── Services/Central/Role/CentralRoleService.php
├── Services/Contracts/Central/Role/CentralRoleServiceInterface.php
├── Repositories/Central/Role/CentralRoleRepository.php
├── Repositories/Contracts/Central/Role/CentralRoleRepositoryInterface.php
└── Database/Migrations/Central/Role/..._create_roles_table.php
bash
php artisan innodite:module-check
bash
php artisan innodite:check-env
bash
php artisan innodite:publish-frontend
php artisan innodite:publish-frontend --force # sobreescribir
bash
# Usar manifiesto por defecto (module-maker-config/migrations/central_order.json)
php artisan innodite:migrate-plan
# Usar manifiesto específico
php artisan innodite:migrate-plan --manifest=tenant_innodite_order.json
# Simular sin tocar BD
php artisan innodite:migrate-plan --manifest=tenant_innodite_order.json --dry-run
# Ejecutar también seeders después de migraciones
php artisan innodite:migrate-plan --manifest=tenant_innodite_order.json --seed
json
{
"migrations": [
"User:Shared/2026_01_01_000001_create_users_table.php",
"Roles:Tenant/Shared/2026_02_01_000001_create_tenant_roles_table.php",
"Custom:Tenant/INNODITE/2026_03_01_000001_innodite_extra_table.php"
],
"seeders": [
"User:Shared/SharedUserSeeder",
"Roles:Tenant/Shared/TenantSharedRoleSeeder",
"Custom:Tenant/INNODITE/TenantINNODITECustomSeeder"
]
}
bash
# Ejecutar una migración específica
php artisan innodite:migrate-one "Products:Tenant/Alpha/2026_01_01_000001_create_products_table.php"
# Forzar un manifiesto concreto
php artisan innodite:migrate-one "Forms:Shared/2026_01_01_000001_create_forms_table.php" --manifest=central_order.json
# Simular sin escribir ni ejecutar
php artisan innodite:migrate-one "Forms:Shared/2026_01_01_000001_create_forms_table.php" --dry-run
# Omitir confirmaciones interactivas
php artisan innodite:migrate-one "Products:Tenant/Alpha/2026_01_01_000001_create_products_table.php" --yes
bash
# Ejecutar un seeder específico
php artisan innodite:seed-one "UserManagement:Tenant/Shared/TenantSharedPermissionSeeder"
# Forzar un manifiesto concreto
php artisan innodite:seed-one "Forms:Shared/SharedFormsSeeder" --manifest=central_order.json
# Simular sin escribir ni ejecutar
php artisan innodite:seed-one "Forms:Shared/SharedFormsSeeder" --dry-run
# Omitir confirmaciones interactivas
php artisan innodite:seed-one "UserManagement:Tenant/Shared/TenantSharedPermissionSeeder" --yes
bash
# Sincronizar automaticamente por contextos (central + tenants detectados)
php artisan innodite:migration-sync
# Sincronizar un manifiesto concreto
php artisan innodite:migration-sync --manifest=tenant_innodite_order.json
# Sincronizacion automatica sin prompt de confirmacion
php artisan innodite:migration-sync --yes
# Ver faltantes sin escribir cambios
php artisan innodite:migration-sync --manifest=tenant_innodite_order.json --dry-run
bash
# Sincronizar un módulo
php artisan innodite:test-sync User
# Sincronizar todos los módulos
php artisan innodite:test-sync --all
Modules/User/
├── Http/Controllers/Shared/User/SharedUserController.php
├── Http/Requests/Shared/User/SharedUserRequest.php
├── Services/Shared/User/SharedUserService.php
├── Services/Contracts/Shared/User/SharedUserServiceInterface.php
├── Repositories/Shared/User/SharedUserRepository.php
├── Repositories/Contracts/Shared/User/SharedUserRepositoryInterface.php
├── Models/Shared/User/SharedUser.php
├── Database/Migrations/Shared/User/XXXX_create_users_table.php
├── Database/Seeders/Shared/User/SharedUserSeeder.php
├── Database/Factories/Shared/User/SharedUserFactory.php
├── Tests/Feature/Shared/SharedUserTest.php
├── Tests/Unit/Shared/SharedUserServiceTest.php
├── Resources/js/Pages/Shared/SharedUserIndex.vue
├── Resources/js/Pages/Shared/SharedUserCreate.vue
├── Resources/js/Pages/Shared/SharedUserEdit.vue
└── Resources/js/Pages/Shared/SharedUserShow.vue
Modules/User/
├── Http/Controllers/Tenant/Shared/User/TenantSharedUserController.php
├── Http/Requests/Tenant/Shared/User/TenantSharedUserRequest.php
├── Services/Tenant/Shared/User/TenantSharedUserService.php
├── Services/Contracts/Tenant/Shared/User/TenantSharedUserServiceInterface.php
├── Repositories/Tenant/Shared/User/TenantSharedUserRepository.php
├── Repositories/Contracts/Tenant/Shared/User/TenantSharedUserRepositoryInterface.php
├── Models/Tenant/Shared/User/TenantSharedUser.php
├── Database/Migrations/Tenant/Shared/User/XXXX_create_users_table.php
├── Database/Seeders/Tenant/Shared/User/TenantSharedUserSeeder.php
├── Database/Factories/Tenant/Shared/User/TenantSharedUserFactory.php
├── Tests/Feature/Tenant/Shared/TenantSharedUserTest.php
├── Tests/Unit/Tenant/Shared/TenantSharedUserServiceTest.php
├── Resources/js/Pages/Tenant/Shared/TenantSharedUserIndex.vue
├── Resources/js/Pages/Tenant/Shared/TenantSharedUserCreate.vue
├── Resources/js/Pages/Tenant/Shared/TenantSharedUserEdit.vue
├── Resources/js/Pages/Tenant/Shared/TenantSharedUserShow.vue
└── Jobs/Tenant/Shared/TenantSharedUserReportJob.php
bash
php artisan vendor:publish --tag=module-maker-stubs
Modules/
└── User/
├── Http/
│ ├── Controllers/
│ │ └── Central/
│ │ └── User/
│ │ └── CentralUserController.php (RendersInertiaModule + JSON)
│ └── Requests/
│ └── Central/
│ └── User/
│ ├── CentralUserStoreRequest.php
│ └── CentralUserUpdateRequest.php
├── Models/
│ └── Central/
│ └── User/
│ └── CentralUser.php (con $table definida)
├── Services/
│ ├── Central/
│ │ └── User/
│ │ └── CentralUserService.php
│ └── Contracts/
│ └── Central/
│ └── User/
│ └── CentralUserServiceInterface.php
├── Repositories/
│ ├── Central/
│ │ └── User/
│ │ └── CentralUserRepository.php
│ └── Contracts/
│ └── Central/
│ └── User/
│ └── CentralUserRepositoryInterface.php
├── Providers/
│ └── UserServiceProvider.php (binding automático Interface↔Implementation)
├── Database/
│ ├── Migrations/
│ │ └── Central/
│ │ └── User/
│ │ └── *_create_users_table.php (migración anónima)
│ ├── Seeders/
│ │ └── Central/
│ │ └── User/
│ │ └── CentralUserSeeder.php
│ └── Factories/
│ └── Central/
│ └── User/
│ └── CentralUserFactory.php
├── Tests/
│ ├── Feature/
│ │ └── Central/
│ │ └── CentralUserTest.php
│ ├── Unit/
│ │ └── Central/
│ │ └── CentralUserServiceTest.php
│ └── Support/
│ └── Central/
│ └── CentralUserSupport.php
├── Resources/
│ └── js/
│ └── Pages/
│ └── Central/
│ ├── CentralUserIndex.vue (lista paginada, axios.get)
│ ├── CentralUserCreate.vue (formulario, axios.post)
│ ├── CentralUserEdit.vue (formulario, axios.get + axios.put)
│ └── CentralUserShow.vue (detalle, axios.get)
├── Jobs/
│ └── Central/
│ └── CentralUserExportJob.php
├── Notifications/
│ └── Central/
│ └── CentralUserWelcomeNotification.php
├── Console/
│ └── Commands/
│ └── Central/
│ └── CentralUserCleanupCommand.php
├── Exceptions/
│ └── Central/
│ └── CentralUserNotFoundException.php
└── Routes/
└── web.php (rutas CRUD — referencia local)