UndefinedVariableSolutionProvider.php
3.0 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
namespace Facade\Ignition\SolutionProviders;
use Facade\Ignition\Exceptions\ViewException;
use Facade\Ignition\Solutions\MakeViewVariableOptionalSolution;
use Facade\Ignition\Solutions\SuggestCorrectVariableNameSolution;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\HasSolutionsForThrowable;
use Throwable;
class UndefinedVariableSolutionProvider implements HasSolutionsForThrowable
{
    private $variableName;
    private $viewFile;
    public function canSolve(Throwable $throwable): bool
    {
        if (! $throwable instanceof ViewException) {
            return false;
        }
        return $this->getNameAndView($throwable) !== null;
    }
    public function getSolutions(Throwable $throwable): array
    {
        $solutions = [];
        extract($this->getNameAndView($throwable));
        if (! isset($variableName)) {
            return [];
        }
        $solutions = $this->findCorrectVariableSolutions($throwable, $variableName, $viewFile);
        $solutions[] = $this->findOptionalVariableSolution($variableName, $viewFile);
        return $solutions;
    }
    protected function findCorrectVariableSolutions(
        ViewException $throwable,
        string $variableName,
        string $viewFile
    ): array {
        return collect($throwable->getViewData())
            ->map(function ($value, $key) use ($variableName) {
                similar_text($variableName, $key, $percentage);
                return ['match' => $percentage, 'value' => $value];
            })
            ->sortByDesc('match')->filter(function ($var) {
                return $var['match'] > 40;
            })
            ->keys()
            ->map(function ($suggestion) use ($variableName, $viewFile) {
                return new SuggestCorrectVariableNameSolution($variableName, $viewFile, $suggestion);
            })
            ->map(function ($solution) {
                return $solution->isRunnable()
                    ? $solution
                    : BaseSolution::create($solution->getSolutionTitle())
                        ->setSolutionDescription($solution->getSolutionDescription());
            })
            ->toArray();
    }
    protected function findOptionalVariableSolution(string $variableName, string $viewFile)
    {
        $optionalSolution = new MakeViewVariableOptionalSolution($variableName, $viewFile);
        return $optionalSolution->isRunnable()
            ? $optionalSolution
            : BaseSolution::create($optionalSolution->getSolutionTitle())
                ->setSolutionDescription($optionalSolution->getSolutionDescription());
    }
    protected function getNameAndView(Throwable $throwable): ?array
    {
        $pattern = '/Undefined variable:? (.*?) \(View: (.*?)\)/';
        preg_match($pattern, $throwable->getMessage(), $matches);
        if (count($matches) === 3) {
            [, $variableName, $viewFile] = $matches;
            $variableName = ltrim($variableName, '$');
            return compact('variableName', 'viewFile');
        }
        return null;
    }
}