baks-dev/products-product
BaksDev Product — модуль продукции для PHP 8.4+: управление продуктами и интеграция с категориями, валютами, деньгами и единицами измерения. Поддерживает установку ассетов, миграции Doctrine и тесты PHPUnit.
composer require baks-dev/products-category baks-dev/reference-money baks-dev/reference-currency baks-dev/reference-measurement baks-dev/products-product
php bin/console baks:assets:install
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
use BaksDev\Products\Product\Entity\Product;
$product = new Product();
$product->setName('Test Product');
$product->setSku('SKU123');
$product->setPrice(19.99); // Assumes reference-money integration
$product->setCurrency('USD'); // Assumes reference-currency integration
$product->save();
src/Entity/ for Product, Category, and related models.src/Migrations/ for schema changes.src/Command/ for baks:assets:install.tests/ for usage examples (run with phpunit --group=products-product).Product CRUD: Use Eloquent or Doctrine repositories (if implemented) for basic operations:
// Create
$product = Product::create([
'name' => 'Premium Widget',
'sku' => 'WIDGET-PREM',
'price' => 49.99,
'currency' => 'EUR',
'measurement' => 'kg', // Assumes reference-measurement
]);
// Read with eager-loaded relationships
$product = Product::with('categories', 'measurementUnit')->find($id);
// Update
$product->setPrice(39.99)->save();
// Delete (soft delete if supported)
$product->delete();
Category Hierarchies:
Leverage products-category for nested categories:
$category = Category::find($id);
$products = $category->products()->with('measurementUnit')->get();
Multi-Currency Pricing:
Integrate with reference-money for dynamic pricing:
$product->setPrice(100, 'USD'); // Stores as 100 USD
$convertedPrice = $product->getPriceIn('EUR'); // Uses reference-money logic
Measurements:
Attach units via reference-measurement:
$product->setMeasurement('500', 'ml'); // 500ml
$measurement = $product->getMeasurementValue(); // Returns 500
$measurementUnit = $product->getMeasurementUnit(); // Returns 'ml'
Service Layer:
Create a service class to encapsulate business logic (e.g., ProductService):
class ProductService {
public function createWithValidation(array $data) {
$validator = Validator::make($data, [
'name' => 'required|string|max:255',
'sku' => 'required|unique:products',
'price' => 'required|numeric',
]);
if ($validator->fails()) {
throw new \InvalidArgumentException($validator->errors()->first());
}
return Product::create($data);
}
}
Events/Observers: Extend functionality with Laravel events (if not natively supported):
// app/Observers/ProductObserver.php
class ProductObserver {
public function saved(Product $product) {
event(new ProductCreated($product));
}
}
Register in AppServiceProvider:
Product::observe(ProductObserver::class);
API Resources: Expose products via Laravel API Resources:
// app/Http/Resources/ProductResource.php
class ProductResource extends JsonResource {
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'sku' => $this->sku,
'price' => $this->price->amount, // Assumes reference-money
'currency' => $this->price->currency->code,
'measurement' => $this->measurement,
'unit' => $this->measurementUnit->symbol,
];
}
}
Bulk Operations:
Use Doctrine’s BulkOperations or Eloquent chunking:
Product::chunk(100, function ($products) {
foreach ($products as $product) {
$product->update(['status' => 'active']);
}
});
Custom Attributes:
Extend the Product entity with dynamic attributes (if needed):
// Add to Product entity
protected $attributes = [
'is_featured' => false,
'weight' => null,
];
// Or use a JSON column for flexible attributes
protected $casts = [
'attributes' => 'json',
];
Migration Conflicts:
products table, migrations may fail. Solution:
php bin/console doctrine:migrations:diff --dump-sql to preview changes.--complete flag.N+1 Query Risks:
// Bad: N+1 queries
$products = Product::all();
foreach ($products as $product) {
$product->categories; // Triggers N queries
}
// Good: Eager-load
$products = Product::with('categories', 'measurementUnit')->get();
Currency/Measurement Dependencies:
reference-money and reference-currency. Ensure these are properly configured:
composer require baks-dev/reference-money baks-dev/reference-currency
php bin/console baks:assets:install
$product->setPrice(100, 'USD');
$product->getPriceIn('EUR'); // Should return converted value
Undocumented Validation:
Product entity for validation annotations or traits.Russian Documentation:
No Built-in API:
spatie/laravel-api for endpoints.Route::apiResource('products', ProductController::class);
Soft Deletes:
Product model uses soft deletes. If so, use:
$product = Product::withTrashed()->find($id);
$product->forceDelete(); // Hard delete
Query Logging: Enable Laravel’s query logging to debug N+1 issues:
DB::enableQueryLog();
Product::with('categories')->get();
dd(DB::getQueryLog());
Doctrine Events: Listen for Doctrine lifecycle events to debug entity changes:
$em->getEventManager()->addEventListener(
\Doctrine\ORM\Events::postPersist,
function ($event) {
$entity = $event->getObject();
\Log::info("Entity {$entity::class} persisted", ['data' => $entity]);
}
);
Console Command Debugging: Add debug output to custom console commands:
public function handle() {
\Log::info('Starting assets install...');
// Command logic
}
Testing: Run the package’s tests to understand expected behavior:
php bin/phpunit --group=products-product
Custom Repositories: Override the default repository for advanced logic:
// config/products.php
'repositories' => [
'product' => \App\Repositories\CustomProductRepository::class,
];
Traits for Reusable Logic: Add traits to extend entities:
// app/Models/Concerns/HasVariants.php
trait HasVariants {
public function variants() {
return $this->hasMany(Variant
How can I help you explore Laravel packages today?