Files
2026-04-28 21:14:25 +03:00

141 lines
4.2 KiB
PHP

<?php
namespace App\Services\WeldLogTriggers\Base;
use App\Services\WeldLogTriggers\Contracts\WeldLogTriggerInterface;
use Illuminate\Support\Facades\Log;
/**
* Base class for all WeldLog triggers
*
* Provides common functionality like timing, logging, and shouldRun logic
*/
abstract class BaseTrigger implements WeldLogTriggerInterface
{
/**
* @var float Start time for performance tracking
*/
protected $startTime;
/**
* @var array Execution context
*/
protected $context = [];
/**
* Get trigger name - must be implemented by child classes
*/
abstract public function getName(): string;
/**
* Get trigger order - must be implemented by child classes
*/
abstract public function getOrder(): int;
/**
* Get dependent fields - must be implemented by child classes
*/
abstract public function getDependentFields(): array;
/**
* Process trigger logic - must be implemented by child classes
*
* @param object $weldLogData Current weld log data
* @param object|null $beforeData Previous weld log data
* @param array $context Execution context
* @return array Result data
*/
abstract protected function process($weldLogData, $beforeData, array $context): array;
/**
* Execute the trigger with logging and error handling
*
* @param object $weldLogData Current weld log data
* @param object|null $beforeData Previous weld log data
* @param array $context Execution context
* @return array Result data
* @throws \Throwable
*/
public function execute($weldLogData, $beforeData = null, array $context = []): array
{
$this->startTime = microtime(true);
$this->context = $context;
Log::info("WeldLog Trigger [{$this->getOrder()}/14] {$this->getName()} - STARTED", [
'weld_log_id' => $weldLogData->id,
'process' => $this->getName()
]);
try {
$result = $this->process($weldLogData, $beforeData, $context);
$this->logCompletion($weldLogData->id, 'success', $result);
return $result;
} catch (\Throwable $th) {
$this->logCompletion($weldLogData->id, 'error', [
'error' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine()
]);
throw $th;
}
}
/**
* Determine if trigger should run based on changed fields
*
* @param array $changedFields List of changed field names
* @param bool $isNewRecord Whether this is a new record
* @return bool
*/
public function shouldRun(array $changedFields, bool $isNewRecord): bool
{
if ($isNewRecord) {
return true;
}
$dependentFields = $this->getDependentFields();
// If no dependent fields defined, always run
if (empty($dependentFields)) {
return true;
}
// Check if any changed field is in dependent fields
return !empty(array_intersect($changedFields, $dependentFields));
}
/**
* Check if trigger is async (default: false)
* Override in child classes if needed
*
* @return bool
*/
public function isAsync(): bool
{
return false;
}
/**
* Log trigger completion with performance metrics
*
* @param int $weldLogId Weld log ID
* @param string $status Execution status (success/error)
* @param array $additionalData Additional log data
*/
protected function logCompletion($weldLogId, string $status, array $additionalData = [])
{
$duration = round((microtime(true) - $this->startTime) * 1000, 2);
$logLevel = $status === 'error' ? 'error' : 'info';
Log::$logLevel("WeldLog Trigger [{$this->getOrder()}/14] {$this->getName()} - COMPLETED", array_merge([
'weld_log_id' => $weldLogId,
'process' => $this->getName(),
'status' => $status,
'duration_ms' => $duration,
'duration_sec' => round($duration / 1000, 3)
], $additionalData));
}
}