Installation
composer require belous/products-bundle
Add the bundle to config/app.php under providers:
Belous\ProductsBundle\ProductsServiceProvider::class,
Publish Configuration
php artisan vendor:publish --provider="Belous\ProductsBundle\ProductsServiceProvider" --tag="config"
Locate the config file at config/products.php and adjust default settings (e.g., default_driver, model, or table).
First Use Case: Product CRUD
Product model (extend Belous\ProductsBundle\Models\Product if needed):
php artisan make:model Product -m
php artisan migrate
routes/web.php:
use Belous\ProductsBundle\Facades\Product;
Route::get('/products', function () {
return Product::all(); // Uses facade for simplicity
});
Key Facade Methods
Product::create([...]) – Create a product.Product::find($id) – Retrieve a product.Product::update($id, [...]) – Update a product.Product::delete($id) – Delete a product.Product::search($query) – Search products (if enabled in config).Repository Pattern Integration
Bind the bundle’s repository to Laravel’s container in AppServiceProvider:
$this->app->bind(
\Belous\ProductsBundle\Repositories\ProductRepository::class,
\Belous\ProductsBundle\Repositories\EloquentProductRepository::class
);
Use dependency injection in controllers:
use Belous\ProductsBundle\Repositories\ProductRepository;
public function __construct(ProductRepository $products) {
$this->products = $products;
}
Event-Driven Extensions
Listen to bundle events (e.g., product.created) in EventServiceProvider:
protected $listen = [
'Belous\ProductsBundle\Events\ProductCreated' => [
'App\Listeners\LogProductCreation',
],
];
API Resource Integration
Use Laravel’s ApiResource for JSON responses:
php artisan make:resource ProductResource
Configure in app/Http/Controllers/ProductController:
return ProductResource::collection(Product::all());
Custom Validation Extend the bundle’s validation rules by publishing assets and overriding:
php artisan vendor:publish --provider="Belous\ProductsBundle\ProductsServiceProvider" --tag="validation"
Add rules to app/Providers/AppServiceProvider:
Validator::extend('custom_rule', function ($attribute, $value, $parameters) {
return $value > 0;
});
Policy Integration
Attach policies to the Product model:
php artisan make:policy ProductPolicy --model=Product
Define rules in app/Policies/ProductPolicy.php:
public function update(User $user, Product $product) {
return $user->isAdmin();
}
Laravel Scout for Search
Enable Scout in config/products.php:
'search' => [
'driver' => 'scout',
],
Index products via:
Product::all()->each->reindex();
Nova/Forge Integration Publish Nova resources:
php artisan vendor:publish --provider="Belous\ProductsBundle\ProductsServiceProvider" --tag="nova"
Register in app/Providers/NovaServiceProvider:
Nova::resources([
\Belous\ProductsBundle\Nova\Product::class,
]);
Queue Jobs for Async Operations Dispatch jobs for heavy operations (e.g., inventory updates):
Product::updated(function ($product) {
UpdateInventoryJob::dispatch($product);
});
Model Binding Conflicts
Product model, ensure the table name matches config/products.php:
protected $table = env('PRODUCTS_TABLE', 'products');
AppServiceProvider:
$this->app->bind(
\Belous\ProductsBundle\Models\Product::class,
\App\Models\CustomProduct::class
);
Facade vs. Dependency Injection
// Bad (facade in service)
$product = Product::find($id);
// Good (injected repository)
$this->products->find($id);
Configuration Overrides
config/products.php) may be merged with defaults. Use config(['products.key' => 'value']) for runtime overrides.Event Subscriber Conflicts
product.*, ensure priority with priority in EventServiceProvider:
'Belous\ProductsBundle\Events\ProductCreated' => [
'App\Listeners\FirstListener' => ['priority' => 10],
'App\Listeners\SecondListener' => ['priority' => 20],
],
Database Transactions
DB::transaction(function () {
Product::update($id, [...]);
// Other DB operations
});
Log Bundle Events Add a listener to log events for debugging:
Event::listen('Belous\ProductsBundle\Events\ProductCreated', function ($event) {
\Log::debug('Product created:', ['id' => $event->product->id]);
});
Check Published Assets
Verify published files (config, validation, views) exist in bootstrap/cache/ after publishing:
php artisan config:clear
php artisan view:clear
Service Provider Loading Order
Ensure ProductsServiceProvider loads after DatabaseServiceProvider and AuthServiceProvider in config/app.php.
Eloquent Debugging
Enable Eloquent logging in .env:
DB_DEBUG=true
Check logs for raw queries:
tail -f storage/logs/laravel.log
Custom Drivers
Implement a custom repository driver by extending Belous\ProductsBundle\Contracts\ProductRepository:
class CustomProductRepository implements ProductRepository {
public function find($id) {
// Custom logic
}
}
Bind it in AppServiceProvider:
$this->app->bind(
\Belous\ProductsBundle\Contracts\ProductRepository::class,
\App\Repositories\CustomProductRepository::class
);
API Response Modifiers
Override the ProductResource to customize JSON responses:
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'custom_field' => $this->customField, // Add custom fields
];
}
Middleware for Product Routes Protect product routes with middleware:
Route::middleware(['auth', 'can:manage-products'])->group(function () {
Route::resource('products', ProductController::class);
});
Testing the Bundle Use Laravel’s testing helpers to mock the repository:
$this->app->instance(
\Belous\ProductsBundle\Contracts\ProductRepository::class,
Mockery::mock(\Belous\ProductsBundle\Contracts\ProductRepository::class)
);
How can I help you explore Laravel packages today?