getSolutionsForThrowable()   B
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 46
rs 8.2448
c 0
b 0
f 0
cc 7
nc 4
nop 1
1
<?php
2
3
namespace Facade\Ignition\SolutionProviders;
4
5
use Facade\IgnitionContracts\HasSolutionsForThrowable;
6
use Facade\IgnitionContracts\ProvidesSolution;
7
use Facade\IgnitionContracts\Solution;
8
use Facade\IgnitionContracts\SolutionProviderRepository as SolutionProviderRepositoryContract;
9
use Illuminate\Support\Collection;
10
use Throwable;
11
12
class SolutionProviderRepository implements SolutionProviderRepositoryContract
13
{
14
    /** @var \Illuminate\Support\Collection */
15
    protected $solutionProviders;
16
17
    public function __construct(array $solutionProviders = [])
18
    {
19
        $this->solutionProviders = Collection::make($solutionProviders);
20
    }
21
22
    public function registerSolutionProvider(string $solutionProviderClass): SolutionProviderRepositoryContract
23
    {
24
        $this->solutionProviders->push($solutionProviderClass);
25
26
        return $this;
27
    }
28
29
    public function registerSolutionProviders(array $solutionProviderClasses): SolutionProviderRepositoryContract
30
    {
31
        $this->solutionProviders = $this->solutionProviders->merge($solutionProviderClasses);
32
33
        return $this;
34
    }
35
36
    public function getSolutionsForThrowable(Throwable $throwable): array
37
    {
38
        $solutions = [];
39
40
        if ($throwable instanceof Solution) {
41
            $solutions[] = $throwable;
42
        }
43
44
        if ($throwable instanceof ProvidesSolution) {
45
            $solutions[] = $throwable->getSolution();
46
        }
47
48
        $providedSolutions = $this->solutionProviders
49
            ->filter(function (string $solutionClass) {
50
                if (! in_array(HasSolutionsForThrowable::class, class_implements($solutionClass))) {
51
                    return false;
52
                }
53
54
                if (in_array($solutionClass, config('ignition.ignored_solution_providers', []))) {
55
                    return false;
56
                }
57
58
                return true;
59
            })
60
            ->map(function (string $solutionClass) {
61
                return app($solutionClass);
62
            })
63
            ->filter(function (HasSolutionsForThrowable $solutionProvider) use ($throwable) {
64
                try {
65
                    return $solutionProvider->canSolve($throwable);
66
                } catch (Throwable $e) {
67
                    return false;
68
                }
69
            })
70
            ->map(function (HasSolutionsForThrowable $solutionProvider) use ($throwable) {
71
                try {
72
                    return $solutionProvider->getSolutions($throwable);
73
                } catch (Throwable $e) {
74
                    return [];
75
                }
76
            })
77
            ->flatten()
78
            ->toArray();
79
80
        return array_merge($solutions, $providedSolutions);
81
    }
82
83
    public function getSolutionForClass(string $solutionClass): ?Solution
84
    {
85
        if (! class_exists($solutionClass)) {
86
            return null;
87
        }
88
89
        if (! in_array(Solution::class, class_implements($solutionClass))) {
90
            return null;
91
        }
92
93
        return app($solutionClass);
94
    }
95
}
96