Вход Регистрация
Файл: vendor/spatie/laravel-ignition/src/Recorders/JobRecorder/JobRecorder.php
Строк: 187
<?php

namespace SpatieLaravelIgnitionRecordersJobRecorder;

use 
DateTime;
use 
Error;
use 
Exception;
use 
IlluminateContractsEncryptionEncrypter;
use 
IlluminateContractsFoundationApplication;
use 
IlluminateContractsQueueJob;
use 
IlluminateQueueCallQueuedClosure;
use 
IlluminateQueueEventsJobExceptionOccurred;
use 
IlluminateQueueJobsRedisJob;
use 
IlluminateSupportStr;
use 
ReflectionClass;
use 
ReflectionProperty;
use 
RuntimeException;

class 
JobRecorder
{
    protected ?
Job $job null;

    public function 
__construct(
        protected 
Application $app,
        protected 
int $maxChainedJobReportingDepth 5,
    ) {
    }

    public function 
start(): self
    
{
        
/** @phpstan-ignore-next-line */
        
$this->app['events']->listen(JobExceptionOccurred::class, [$this'record']);

        return 
$this;
    }

    public function 
record(JobExceptionOccurred $event): void
    
{
        
$this->job $event->job;
    }

    
/**
     * @return array<string, mixed>|null
     */
    
public function getJob(): ?array
    {
        if (
$this->job === null) {
            return 
null;
        }

        return 
array_merge(
            
$this->getJobProperties(),
            [
                
'name' => $this->job->resolveName(),
                
'connection' => $this->job->getConnectionName(),
                
'queue' => $this->job->getQueue(),
            ]
        );
    }

    public function 
reset(): void
    
{
        
$this->job null;
    }

    protected function 
getJobProperties(): array
    {
        
$payload collect($this->resolveJobPayload());

        
$properties = [];

        foreach (
$payload as $key => $value) {
            if (! 
in_array($key, ['job''data''displayName'])) {
                
$properties[$key] = $value;
            }
        }

        if (
$pushedAt DateTime::createFromFormat('U.u'$payload->get('pushedAt'''))) {
            
$properties['pushedAt'] = $pushedAt->format(DATE_ATOM);
        }

        try {
            
$properties['data'] = $this->resolveCommandProperties(
                
$this->resolveObjectFromCommand($payload['data']['command']),
                
$this->maxChainedJobReportingDepth
            
);
        } catch (
Exception $exception) {
        }

        return 
$properties;
    }

    protected function 
resolveJobPayload(): array
    {
        if (! 
$this->job instanceof RedisJob) {
            return 
$this->job->payload();
        }

        try {
            return 
json_decode($this->job->getReservedJob(), true512JSON_THROW_ON_ERROR);
        } catch (
Exception $e) {
            return 
$this->job->payload();
        }
    }

    protected function 
resolveCommandProperties(object $commandint $maxChainDepth): array
    {
        
$propertiesToIgnore = ['job''closure'];

        
$properties collect((new ReflectionClass($command))->getProperties())
            ->
reject(function (ReflectionProperty $property) use ($propertiesToIgnore) {
                return 
in_array($property->name$propertiesToIgnore);
            })
            ->
mapWithKeys(function (ReflectionProperty $property) use ($command) {
                try {
                    
$property->setAccessible(true);

                    return [
$property->name => $property->getValue($command)];
                } catch (
Error $error) {
                    return [
$property->name => 'uninitialized'];
                }
            });

        if (
$properties->has('chained')) {
            
$properties['chained'] = $this->resolveJobChain($properties->get('chained'), $maxChainDepth);
        }

        return 
$properties->all();
    }

    
/**
     * @param array<string, mixed> $chainedCommands
     * @param int $maxDepth
     *
     * @return array
     */
    
protected function resolveJobChain(array $chainedCommandsint $maxDepth): array
    {
        if (
$maxDepth === 0) {
            return [
'Ignition stopped recording jobs after this point since the max chain depth was reached'];
        }

        return 
array_map(
            function (
string $command) use ($maxDepth) {
                
$commandObject $this->resolveObjectFromCommand($command);

                return [
                    
'name' => $commandObject instanceof CallQueuedClosure $commandObject->displayName() : get_class($commandObject),
                    
'data' => $this->resolveCommandProperties($commandObject$maxDepth 1),
                ];
            },
            
$chainedCommands
        
);
    }

    
// Taken from IlluminateQueueCallQueuedHandler
    
protected function resolveObjectFromCommand(string $command): object
    
{
        if (
Str::startsWith($command'O:')) {
            return 
unserialize($command);
        }

        if (
$this->app->bound(Encrypter::class)) {
            
/** @phpstan-ignore-next-line */
            
return unserialize($this->app[Encrypter::class]->decrypt($command));
        }

        throw new 
RuntimeException('Unable to extract job payload.');
    }
}
Онлайн: 0
Реклама