laravel-shop/src/Models/ProductAction.php

123 lines
3.5 KiB
PHP
Raw Normal View History

2025-11-21 10:49:41 +00:00
<?php
namespace Blax\Shop\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Log;
class ProductAction extends Model
{
use HasUuids;
protected $fillable = [
'product_id',
'event',
'action_type',
2025-11-22 17:09:45 +00:00
'parameters',
2025-11-21 10:49:41 +00:00
'active',
'sort_order',
];
protected $casts = [
2025-11-22 17:09:45 +00:00
'parameters' => 'array',
2025-11-21 10:49:41 +00:00
'active' => 'boolean',
'sort_order' => 'integer',
];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->setTable(config('shop.tables.product_actions', 'product_actions'));
}
public function product(): BelongsTo
{
return $this->belongsTo(config('shop.models.product', Product::class));
}
public static function callForProduct(
Product $product,
string $event,
?ProductPurchase $productPurchase = null,
array $additionalData = []
): void {
$actions = $product->actions()
->where('event', $event)
->where('active', true)
->orderBy('sort_order')
->get();
if ($actions->isEmpty()) {
return;
}
$available_actions = self::getAvailableActions();
foreach ($actions as $action) {
try {
if (!isset($available_actions[$action->action_type])) {
Log::warning('Product action not found', [
'product_id' => $product->id,
'event' => $event,
'action_type' => $action->action_type,
]);
continue;
}
$namespace = config('shop.actions.namespace', 'App\\Jobs\\ProductAction');
$action_job = $namespace . '\\' . $action->action_type;
$params = [
'product' => $product,
'productPurchase' => $productPurchase,
'event' => $event,
2025-11-22 17:09:45 +00:00
...($action->parameters ?? []),
2025-11-21 10:49:41 +00:00
...$additionalData,
];
dispatch(new $action_job(...$params));
} catch (\Exception $e) {
Log::error('Error calling product action', [
'product_id' => $product->id,
'event' => $event,
'action_type' => $action->action_type ?? 'unknown',
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
report($e);
}
}
}
public function execute(
Product $product,
?ProductPurchase $productPurchase = null,
array $additionalData = []
): void {
$namespace = config('shop.actions.namespace', 'App\\Jobs\\ProductAction');
$action_job = $namespace . '\\' . $this->action_type;
if (!class_exists($action_job)) {
throw new \Exception("Action class {$action_job} not found");
}
$params = [
'product' => $product,
'productPurchase' => $productPurchase,
'event' => $this->event,
2025-11-22 17:09:45 +00:00
...($this->parameters ?? []),
2025-11-21 10:49:41 +00:00
...$additionalData,
];
dispatch(new $action_job(...$params));
}
2025-11-25 16:14:00 +00:00
public static function getAvailableActions(): array
{
return config('shop.actions.available', []);
}
2025-11-21 10:49:41 +00:00
}