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

namespace SpatieLaravelIgnitionViews;

use 
Exception;
use 
IlluminateContractsViewEngine;
use 
IlluminateFoundationApplication;
use 
IlluminateSupportArr;
use 
IlluminateSupportCollection;
use 
IlluminateViewEnginesPhpEngine;
use 
IlluminateViewViewException;
use 
ReflectionClass;
use 
ReflectionProperty;
use 
SpatieIgnitionContractsProvidesSolution;
use 
SpatieLaravelIgnitionExceptionsViewException as IgnitionViewException;
use 
SpatieLaravelIgnitionExceptionsViewExceptionWithSolution;
use 
Throwable;

class 
ViewExceptionMapper
{
    protected 
Engine $compilerEngine;
    protected 
BladeSourceMapCompiler $bladeSourceMapCompiler;
    protected array 
$knownPaths;

    public function 
__construct(BladeSourceMapCompiler $bladeSourceMapCompiler)
    {
        
$resolver app('view.engine.resolver');

        
$this->compilerEngine $resolver->resolve('blade');

        
$this->bladeSourceMapCompiler $bladeSourceMapCompiler;
    }

    public function 
map(ViewException $viewException): IgnitionViewException
    
{
        
$baseException $this->getRealException($viewException);

        if (
$baseException instanceof IgnitionViewException) {
            return 
$baseException;
        }

        
preg_match('/(View: (?P<path>.*?))/'$viewException->getMessage(), $matches);

        
$compiledViewPath $matches['path'];

        
$exception $this->createException($baseException);

        if (
$baseException instanceof ProvidesSolution) {
            
/** @var ViewExceptionWithSolution $exception */
            
$exception->setSolution($baseException->getSolution());
        }

        
$this->modifyViewsInTrace($exception);

        
$exception->setView($compiledViewPath);
        
$exception->setViewData($this->getViewData($exception));

        return 
$exception;
    }

    protected function 
createException(Throwable $baseException): IgnitionViewException
    
{
        
$viewExceptionClass $baseException instanceof ProvidesSolution
            
ViewExceptionWithSolution::class
            : 
IgnitionViewException::class;

        
$viewFile $this->findCompiledView($baseException->getFile());
        
$file $viewFile ?? $baseException->getFile();
        
$line $viewFile $this->getBladeLineNumber($file$baseException->getLine()) : $baseException->getLine();

        return new 
$viewExceptionClass(
            
$baseException->getMessage(),
            
0,
            
1,
            
$file,
            
$line,
            
$baseException
        
);
    }

    protected function 
modifyViewsInTrace(IgnitionViewException $exception): void
    
{
        
$trace Collection::make($exception->getPrevious()->getTrace())
            ->
map(function ($trace) {
                if (
$originalPath $this->findCompiledView(Arr::get($trace'file'''))) {
                    
$trace['file'] = $originalPath;
                    
$trace['line'] = $this->getBladeLineNumber($trace['file'], $trace['line']);
                }

                return 
$trace;
            })->
toArray();

        
$traceProperty = new ReflectionProperty('Exception''trace');
        
$traceProperty->setAccessible(true);
        
$traceProperty->setValue($exception$trace);
    }

    
/**
     * Look at the previous exceptions to find the original exception.
     * This is usually the first Exception that is not a ViewException.
     */
    
protected function getRealException(Throwable $exception): Throwable
    
{
        
$rootException $exception->getPrevious() ?? $exception;

        while (
$rootException instanceof ViewException && $rootException->getPrevious()) {
            
$rootException $rootException->getPrevious();
        }

        return 
$rootException;
    }

    protected function 
findCompiledView(string $compiledPath): ?string
    
{
        
$this->knownPaths ??= $this->getKnownPaths();

        return 
$this->knownPaths[$compiledPath] ?? null;
    }

    protected function 
getKnownPaths(): array
    {
        
$compilerEngineReflection = new ReflectionClass($this->compilerEngine);

        if (! 
$compilerEngineReflection->hasProperty('lastCompiled') && $compilerEngineReflection->hasProperty('engine')) {
            
$compilerEngine $compilerEngineReflection->getProperty('engine');
            
$compilerEngine->setAccessible(true);
            
$compilerEngine $compilerEngine->getValue($this->compilerEngine);
            
$lastCompiled = new ReflectionProperty($compilerEngine'lastCompiled');
            
$lastCompiled->setAccessible(true);
            
$lastCompiled $lastCompiled->getValue($compilerEngine);
        } else {
            
$lastCompiled $compilerEngineReflection->getProperty('lastCompiled');
            
$lastCompiled->setAccessible(true);
            
$lastCompiled $lastCompiled->getValue($this->compilerEngine);
        }

        
$knownPaths = [];
        foreach (
$lastCompiled as $lastCompiledPath) {
            
$compiledPath $this->compilerEngine->getCompiler()->getCompiledPath($lastCompiledPath);

            
$knownPaths[$compiledPath ?? $lastCompiledPath] = $lastCompiledPath;
        }

        return 
$knownPaths;
    }

    protected function 
getBladeLineNumber(string $viewint $compiledLineNumber): int
    
{
        return 
$this->bladeSourceMapCompiler->detectLineNumber($view$compiledLineNumber);
    }

    protected function 
getViewData(Throwable $exception): array
    {
        foreach (
$exception->getTrace() as $frame) {
            if (
Arr::get($frame'class') === PhpEngine::class) {
                
$data Arr::get($frame'args.1', []);

                return 
$this->filterViewData($data);
            }
        }

        return [];
    }

    protected function 
filterViewData(array $data): array
    {
        
// By default, Laravel views get two data keys:
        // __env and app. We try to filter them out.
        
return array_filter($data, function ($value$key) {
            if (
$key === 'app') {
                return ! 
$value instanceof Application;
            }

            return 
$key !== '__env';
        }, 
ARRAY_FILTER_USE_BOTH);
    }
}
Онлайн: 1
Реклама