Completed
Push — master ( 58a826...fc9eaa )
by Freek
01:37 queued 10s
created

getSolutionDescription()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Facade\Ignition\SolutionProviders;
4
5
use Throwable;
6
use ReflectionClass;
7
use ReflectionMethod;
8
use BadMethodCallException;
9
use Illuminate\Support\Str;
10
use Illuminate\Support\Collection;
11
use Illuminate\Validation\Validator;
12
use Facade\IgnitionContracts\BaseSolution;
13
use Facade\Ignition\Support\StringComparator;
14
use Facade\IgnitionContracts\HasSolutionsForThrowable;
15
16
class UnknownValidationSolutionProvider implements HasSolutionsForThrowable
17
{
18
    protected const REGEX = '/Illuminate\\\\Validation\\\\Validator::(?P<method>validate(?!(Attribute|UsingCustomRule))[A-Z][a-zA-Z]+)/m';
19
20
    public function canSolve(Throwable $throwable): bool
21
    {
22
        if (! $throwable instanceof BadMethodCallException) {
23
            return false;
24
        }
25
26
        return ! is_null($this->getMethodFromExceptionMessage($throwable->getMessage()));
27
    }
28
29
    public function getSolutions(Throwable $throwable): array
30
    {
31
        return [
32
            BaseSolution::create('Unknown Validation Rule')
33
                ->setSolutionDescription($this->getSolutionDescription($throwable)),
34
        ];
35
    }
36
37
    protected function getSolutionDescription(Throwable $throwable): string
38
    {
39
        $method = $this->getMethodFromExceptionMessage($throwable->getMessage());
40
41
        $possibleMethod = StringComparator::findSimilarText(
42
            $this->getAvailableMethods()->toArray(),
43
            $method
44
        );
45
46
        if (empty($possibleMethod)) {
47
            return '';
48
        }
49
50
        $rule = Str::snake(str_replace('validate', '', $possibleMethod));
51
52
        return "Did you mean `{$rule}` ?";
53
    }
54
55
    protected function getMethodFromExceptionMessage(string $message): ?string
56
    {
57
        if (! preg_match(self::REGEX, $message, $matches)) {
58
            return null;
59
        }
60
61
        return $matches['method'];
62
    }
63
64
    protected function getAvailableMethods(): Collection
65
    {
66
        $class = new ReflectionClass(Validator::class);
67
68
        $extensions = Collection::make((app('validator')->make([], []))->extensions)
69
            ->keys()
70
            ->map(function (string $extension) {
71
                return 'validate'.Str::studly($extension);
72
            });
73
74
        return Collection::make($class->getMethods())
75
            ->filter(function (ReflectionMethod $method) {
76
                return preg_match('/(validate(?!(Attribute|UsingCustomRule))[A-Z][a-zA-Z]+)/', $method->name);
77
            })
78
            ->map(function (ReflectionMethod $method) {
79
                return $method->name;
80
            })
81
            ->merge($extensions);
82
    }
83
}
84