LaravelPackages.net
Acme Inc.
Toggle sidebar
rawnoq/laravel-hmvc

A professional Laravel package for Hierarchical Model-View-Controller (HMVC) architecture with complete modular structure support

112
0
1.1.0
About rawnoq/laravel-hmvc

rawnoq/laravel-hmvc is a Laravel package for a professional laravel package for hierarchical model-view-controller (hmvc) architecture with complete modular structure support. It currently has 0 GitHub stars and 112 downloads on Packagist (latest version 1.1.0). Install it with composer require rawnoq/laravel-hmvc. Discover more Laravel packages by rawnoq or browse all Laravel packages to compare alternatives.

Last updated

Laravel HMVC Package

A professional, feature-rich Hierarchical Model-View-Controller (HMVC) package for Laravel applications. This package provides a complete modular architecture solution with automatic route loading, view registration, migration management, and comprehensive Artisan command support.

πŸ“‹ Table of Contents

✨ Features

Core Features

  • βœ… Complete HMVC Architecture - Organize your application into independent, reusable modules
  • βœ… Automatic Route Loading - Routes are automatically discovered and loaded from modules
  • βœ… View Registration - Module views are automatically registered with Laravel
  • βœ… Translation Support - Automatic language file loading from modules
  • βœ… Migration Management - Module-specific migrations with dedicated commands
  • βœ… Service Provider Support - Each module can have its own service providers
  • βœ… Configuration Management - Module-specific configuration files
  • βœ… Module Status Management - Enable/disable modules dynamically

Artisan Commands

  • βœ… Make Commands - Full support for creating components within modules
  • βœ… Module Management Commands - Create, list, enable, disable modules
  • βœ… Migration & Seeding - Module-specific database operations
  • βœ… Case-Insensitive - Module names work regardless of case

Supported Components

All Laravel make: commands support the --module option:

  • Controllers, Models, Requests, Factories, Seeders, Migrations, Policies
  • Middleware, Commands, Events, Listeners, Observers
  • Resources, Tests, Notifications, Mail, Jobs, Exceptions
  • Rules, Casts, Channels, Components, Enums, Scopes
  • Views, Classes, Interfaces, Traits, DTOs, Config, Providers, Job Middleware

πŸ“¦ Requirements

  • PHP 8.2 or higher
  • Laravel 11.0+ or Laravel 12.0+

πŸš€ Installation

Step 1: Install via Composer

composer require rawnoq/laravel-hmvc

The package will automatically register PSR-4 autoloading for your modules. No manual configuration needed!

Step 2: Publish Configuration (Optional)

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

This will publish the configuration file to config/hmvc.php.

Step 3: Publish Stubs (Optional)

php artisan vendor:publish --tag=hmvc-stubs

This will publish module stubs to stubs/hmvc/module/ for customization.

⚠️ Note on Autoloading

The package automatically registers PSR-4 autoloading for the Modules namespace. You do not need to manually add it to your composer.json. The autoloading is registered programmatically and works on both Linux and Windows systems.

🎯 Quick Start

Create Your First Module

php artisan module:make Blog

This command will create a complete module structure:

modules/
└── Blog/
    β”œβ”€β”€ Config/
    β”‚   └── config.php
    β”œβ”€β”€ Database/
    β”‚   β”œβ”€β”€ Factories/
    β”‚   β”œβ”€β”€ Migrations/
    β”‚   └── Seeders/
    β”‚       └── DatabaseSeeder.php
    β”œβ”€β”€ Http/
    β”‚   β”œβ”€β”€ Controllers/
    β”‚   β”‚   └── BlogController.php
    β”‚   β”œβ”€β”€ Middleware/
    β”‚   β”œβ”€β”€ Requests/
    β”‚   └── Resources/
    β”œβ”€β”€ Providers/
    β”‚   └── ServiceProvider.php
    β”œβ”€β”€ Resources/
    β”‚   β”œβ”€β”€ lang/
    β”‚   └── views/
    β”œβ”€β”€ Routes/
    β”‚   β”œβ”€β”€ web.php
    β”‚   └── api.php
    └── Models/

Create Components Within Modules

# Create a controller in a module
php artisan make:controller PostController --module=Blog

# Create a model with migration and factory
php artisan make:model Post --module=Blog --migration --factory

# Create a request
php artisan make:request StorePostRequest --module=Blog

# Create middleware
php artisan make:middleware CheckAuth --module=Blog

πŸ“š Module Management

List All Modules

php artisan module:list

Output:

+--------+---------+--------+-------------+-----------+------------+-------+
| Module | Status  | Routes | Controllers | Providers | Migrations | Views |
+--------+---------+--------+-------------+-----------+------------+-------+
| Blog   | Enabled | βœ“      | βœ“           | βœ“         | βœ“          | βœ“     |
| User   | Enabled | βœ“      | βœ“           | βœ“         | βœ—          | βœ“     |
+--------+---------+--------+-------------+-----------+------------+-------+

Enable/Disable Modules

# Enable a module
php artisan module:enable Blog

# Disable a module
php artisan module:disable Blog

Run Module Migrations

# Run migrations for a specific module
php artisan module:migrate Blog

# Run migrations with seeding
php artisan module:migrate Blog --seed

Run Module Seeders

php artisan module:seed Blog

πŸ› οΈ Artisan Commands

Module Management Commands

| Command | Description | |---------|-------------| | module:make {name} | Create a new HMVC module scaffold | | module:list | List all registered HMVC modules | | module:enable {name} | Enable a disabled HMVC module | | module:disable {name} | Disable an HMVC module | | module:migrate {name} | Run database migrations for a specific module | | module:seed {name} | Run the database seeder for a specific module |

Module Options

The module:make command supports several options:

# Create a module with force (overwrite if exists)
php artisan module:make Blog --force

# Create a plain module (no scaffold)
php artisan module:make Blog --plain

# Create a module with API routing scaffold
php artisan module:make Blog --api

Make Commands with Module Support

All Laravel make: commands support the --module option:

Basic Components

php artisan make:controller PostController --module=Blog
php artisan make:model Post --module=Blog
php artisan make:request StorePostRequest --module=Blog
php artisan make:middleware CheckAuth --module=Blog
php artisan make:policy PostPolicy --module=Blog

Database Components

php artisan make:migration create_posts_table --module=Blog
php artisan make:factory PostFactory --module=Blog
php artisan make:seeder PostSeeder --module=Blog

Event System

php artisan make:event PostCreated --module=Blog
php artisan make:listener SendPostNotification --module=Blog
php artisan make:observer PostObserver --module=Blog

Jobs & Queues

php artisan make:job ProcessPost --module=Blog
php artisan make:job-middleware RateLimitMiddleware --module=Blog

API & Resources

php artisan make:resource PostResource --module=Blog
php artisan make:test PostTest --module=Blog

Notifications & Mail

php artisan make:notification PostPublished --module=Blog
php artisan make:mail PostMail --module=Blog

Validation & Rules

php artisan make:rule CustomRule --module=Blog
php artisan make:cast JsonCast --module=Blog

Broadcasting

php artisan make:channel PostChannel --module=Blog

View Components

php artisan make:component PostCard --module=Blog
php artisan make:view post.show --module=Blog

Other Components

php artisan make:command ProcessCommand --module=Blog
php artisan make:enum PostStatus --module=Blog
php artisan make:scope PublishedScope --module=Blog
php artisan make:class PostService --module=Blog
php artisan make:interface PostRepositoryInterface --module=Blog
php artisan make:trait HasSlug --module=Blog
php artisan make:dto PostDto --module=Blog
php artisan make:config post --module=Blog
php artisan make:provider PostServiceProvider --module=Blog
php artisan make:exception PostNotFoundException --module=Blog

Note: All commands work normally without --module option (standard Laravel behavior).

πŸ“ Module Structure

A typical module structure looks like this (matching Laravel's standard structure):

modules/
└── Blog/
    β”œβ”€β”€ App/
    β”‚   β”œβ”€β”€ Http/
    β”‚   β”‚   β”œβ”€β”€ Controllers/         # Controllers
    β”‚   β”‚   β”œβ”€β”€ Middleware/          # HTTP middleware
    β”‚   β”‚   β”œβ”€β”€ Requests/            # Form requests
    β”‚   β”‚   └── Resources/           # API resources
    β”‚   β”œβ”€β”€ Models/                  # Eloquent models
    β”‚   β”œβ”€β”€ Providers/
    β”‚   β”‚   └── ServiceProvider.php  # Module service provider
    β”‚   β”œβ”€β”€ Policies/                # Authorization policies
    β”‚   β”œβ”€β”€ Events/                  # Event classes
    β”‚   β”œβ”€β”€ Listeners/               # Event listeners
    β”‚   β”œβ”€β”€ Observers/               # Model observers
    β”‚   β”œβ”€β”€ Notifications/           # Notification classes
    β”‚   β”œβ”€β”€ Mail/                    # Mail classes
    β”‚   β”œβ”€β”€ Jobs/                    # Job classes
    β”‚   β”œβ”€β”€ Exceptions/              # Exception classes
    β”‚   β”œβ”€β”€ Rules/                   # Validation rules
    β”‚   β”œβ”€β”€ Casts/                   # Custom casts
    β”‚   β”œβ”€β”€ Broadcasting/            # Broadcasting channels
    β”‚   β”œβ”€β”€ View/
    β”‚   β”‚   └── Components/          # View components
    β”‚   β”œβ”€β”€ Enums/                   # Enums
    β”‚   β”œβ”€β”€ Console/
    β”‚   β”‚   └── Commands/            # Artisan commands
    β”‚   β”œβ”€β”€ Interfaces/              # Interfaces
    β”‚   β”œβ”€β”€ Traits/                  # Traits
    β”‚   └── DTOs/                    # Data Transfer Objects
    β”œβ”€β”€ Database/
    β”‚   β”œβ”€β”€ Factories/               # Model factories
    β”‚   β”œβ”€β”€ Migrations/              # Database migrations
    β”‚   └── Seeders/                 # Database seeders
    β”œβ”€β”€ Resources/
    β”‚   β”œβ”€β”€ Lang/                    # Translation files
    β”‚   └── Views/                   # Blade views
    β”œβ”€β”€ Routes/
    β”‚   β”œβ”€β”€ web.php                  # Web routes
    β”‚   └── api.php                  # API routes
    β”œβ”€β”€ Config/
    β”‚   └── config.php               # Module configuration
    └── Tests/                       # Test classes

βš™οΈ Configuration

The configuration file is located at config/hmvc.php:

return [
    // Module namespace
    'namespace' => 'Modules',

    // Modules directory path
    'modules_path' => base_path('modules'),

    // Status file location
    'status_file' => storage_path('app/hmvc/modules.php'),

    // Directory structure for modules
    'directories' => [
        'controllers' => ['App/Http/Controllers'],
        'models' => ['App/Models'],
        'requests' => ['App/Http/Requests'],
        // ... and more
    ],

    // Route configuration
    'routes' => [
        [
            'name' => 'web',
            'path' => 'routes/web.php',
            'middleware' => ['web'],
            'prefix' => null,
            'enabled' => true,
        ],
        [
            'name' => 'api',
            'path' => 'routes/api.php',
            'middleware' => ['api'],
            'prefix' => 'api',
            'enabled' => true,
        ],
    ],
];

Customizing Module Directories

You can customize the directory structure in config/hmvc.php:

'directories' => [
    'controllers' => ['App/Http/Controllers', 'Controllers'],
    'models' => ['App/Models', 'Entities'],
    // Add custom directories
],

πŸŽ“ Advanced Usage

Module Service Providers

Each module can have its own service provider located at Providers/ServiceProvider.php:

<?php

namespace Modules\Blog\Providers;

use Illuminate\Support\ServiceProvider;

class ServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Register module services
    }

    public function boot(): void
    {
        // Boot module services
    }
}

Registering Class Aliases

The package provides two ways to register class aliases:

1. Using the Helper Function (Recommended):

Single alias:

<?php

namespace Modules\Authentication\App\Providers;

use Illuminate\Support\ServiceProvider;

class ServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        register_class_alias(
            'Modules\Authentication\App\Models\BaseUser',
            config('authentication_dependencies.models.user')
        );
    }
}

Multiple aliases at once (snake_case):

<?php

namespace Modules\Authentication\App\Providers;

use Illuminate\Support\ServiceProvider;

class ServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        register_class_aliases([
            'Modules\Authentication\App\Models\BaseUser' => config('authentication_dependencies.models.user'),
            'Modules\Authentication\App\Http\Resources\UserResource' => config('authentication_dependencies.resources.user'),
        ]);
    }
}

Multiple aliases at once (camelCase):

<?php

namespace Modules\Authentication\App\Providers;

use Illuminate\Support\ServiceProvider;

class ServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        registerClassAliases([
            'Modules\Authentication\App\Models\BaseUser' => config('authentication_dependencies.models.user'),
            'Modules\Authentication\App\Http\Resources\UserResource' => config('authentication_dependencies.resources.user'),
        ]);
    }
}

Note: Both register_class_aliases() (snake_case) and registerClassAliases() (camelCase) are available. Use whichever naming convention you prefer.

2. Using the Trait:

<?php

namespace Modules\Authentication\App\Providers;

use Illuminate\Support\ServiceProvider;
use Rawnoq\HMVC\Support\RegistersClassAliases;

class ServiceProvider extends ServiceProvider
{
    use RegistersClassAliases;

    public function register(): void
    {
        $this->registerClassAlias(
            'Modules\Authentication\App\Models\BaseUser',
            config('authentication_dependencies.models.user')
        );
    }
}

Benefits:

  • Allows modules to reference classes by a consistent name
  • Actual implementation can be swapped via configuration
  • Prevents duplicate alias registration
  • Type-safe and maintainable

Module Routes

Web Routes (routes/web.php)

<?php

use Modules\Blog\App\Http\Controllers\BlogController;
use Illuminate\Support\Facades\Route;

Route::get('/blog', [BlogController::class, 'index']);
Route::get('/blog/{post}', [BlogController::class, 'show']);

API Routes (routes/api.php)

<?php

use Modules\Blog\App\Http\Controllers\BlogController;
use Illuminate\Support\Facades\Route;

Route::apiResource('posts', BlogController::class);

Module Views

Views are automatically registered with the module name as namespace:

// In controller
return view('blog::posts.index', ['posts' => $posts]);

// In Blade
@include('blog::partials.header')

Module Translations

Translation files are automatically loaded:

// In code
trans('blog::messages.welcome');

// In Blade
{{ __('blog::messages.welcome') }}

Module Migrations

Migrations are automatically discovered and can be run with:

php artisan module:migrate Blog

Or run all migrations (including modules):

php artisan migrate

Module Configuration

Access module configuration:

config('blog.some_key');

πŸ“ Examples

Example 1: Complete Blog Module

# Create module
php artisan module:make Blog

# Create models
php artisan make:model Post --module=Blog --migration --factory
php artisan make:model Category --module=Blog --migration --factory

# Create controllers
php artisan make:controller PostController --module=Blog --resource
php artisan make:controller CategoryController --module=Blog --resource

# Create requests
php artisan make:request StorePostRequest --module=Blog
php artisan make:request UpdatePostRequest --module=Blog

# Create policies
php artisan make:policy PostPolicy --module=Blog --model=Post

# Create seeders
php artisan make:seeder PostSeeder --module=Blog

Example 2: API Module with Events

# Create module
php artisan module:make Api --plain

# Create components
php artisan make:model User --module=Api --migration
php artisan make:event UserCreated --module=Api
php artisan make:listener SendWelcomeEmail --module=Api --event=UserCreated
php artisan make:job ProcessUserRegistration --module=Api
php artisan make:notification WelcomeNotification --module=Api

Example 3: E-commerce Module

# Create module
php artisan module:make Ecommerce

# Create models
php artisan make:model Product --module=Ecommerce --migration --factory
php artisan make:model Order --module=Ecommerce --migration --factory
php artisan make:model Cart --module=Ecommerce --migration

# Create services
php artisan make:class ProductService --module=Ecommerce
php artisan make:class OrderService --module=Ecommerce

# Create repositories
php artisan make:interface ProductRepositoryInterface --module=Ecommerce
php artisan make:class ProductRepository --module=Ecommerce

# Create DTOs
php artisan make:dto CreateProductDto --module=Ecommerce
php artisan make:dto UpdateOrderDto --module=Ecommerce

πŸ”§ Troubleshooting

Module Not Found

If you get "Module does not exist" error:

  1. Check module name (case-insensitive)
  2. Verify module exists in modules/ directory
  3. Run php artisan module:list to see all modules

Routes Not Loading

  1. Ensure module is enabled: php artisan module:enable ModuleName
  2. Check route files exist: modules/ModuleName/routes/web.php or api.php
  3. Clear route cache: php artisan route:clear

Views Not Found

  1. Verify view files exist in modules/ModuleName/Resources/views/
  2. Use correct namespace: module-name::view.name
  3. Clear view cache: php artisan view:clear

πŸ§ͺ Testing

composer test

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Please see CONTRIBUTING.md for more details.

πŸ“„ License

This package is open-sourced software licensed under the MIT license.

πŸ“¦ Data Transfer Objects (DTOs)

The package includes a powerful DTO system with a base class for type-safe data transfer:

Creating DTOs

# Create a DTO in app
php artisan make:dto UserDto

# Create a DTO in a module
php artisan make:dto PostDto --module=Blog

DTO Structure

All DTOs extend Rawnoq\HMVC\DTOs\BaseDto which provides:

  • fromArray(array $data): static - Create DTO from array
  • fromRequest(Request $request): static - Create DTO from validated request
  • toArray(): array - Convert DTO to array

Example DTO

<?php

namespace Modules\Blog\App\DTOs;

use Rawnoq\HMVC\DTOs\BaseDto;

final readonly class PostDto extends BaseDto
{
    public function __construct(
        public string $title,
        public string $content,
        public ?string $slug = null,
    ) {}

    public static function fromArray(array $data): static
    {
        return new static(
            title: $data['title'],
            content: $data['content'],
            slug: $data['slug'] ?? null,
        );
    }

    public function toArray(): array
    {
        return [
            'title' => $this->title,
            'content' => $this->content,
            'slug' => $this->slug,
        ];
    }
}

Using DTOs

// In a controller
use Modules\Blog\App\DTOs\PostDto;

public function store(StorePostRequest $request)
{
    $dto = PostDto::fromRequest($request);
    
    // Use DTO with type safety
    $post = Post::create($dto->toArray());
    
    return response()->json($post);
}

πŸ™ Credits

  • Author: Rawnoq
  • Package: rawnoq/laravel-hmvc
  • Version: 1.0.3

πŸ“š Additional Resources


Made with ❀️ for the Laravel community

Comments