SeoComposer   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 9
Bugs 1 Features 0
Metric Value
wmc 8
eloc 36
c 9
b 1
f 0
dl 0
loc 98
ccs 40
cts 40
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getSeoTags() 0 29 3
A getMaxWildcardLevels() 0 3 1
A __construct() 0 3 1
A compose() 0 9 2
A wildcard() 0 14 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\SeoManager\Composers;
6
7
use Illuminate\Support\Str;
8
use Illuminate\View\View;
9
use MichaelRubel\EnhancedContainer\Call;
10
use MichaelRubel\SeoManager\Contracts\SeoTagContract;
11
use MichaelRubel\SeoManager\Exceptions\ShouldImplementSeoTagInterfaceException;
12
use MichaelRubel\SeoManager\Models\SeoTag;
13
14
class SeoComposer
15
{
16
    /**
17
     * SeoComposer constructor.
18
     *
19
     * @throws ShouldImplementSeoTagInterfaceException
20
     */
21 10
    public function __construct(protected mixed $seo_manager = null)
22
    {
23 10
        $this->seo_manager = $this->getSeoTags();
24
    }
25
26
    /**
27
     * Bind data to the view.
28
     *
29
     * @param  View  $view
30
     * @return void
31
     */
32 9
    public function compose(View $view): void
33
    {
34 9
        $variable = config('seo-manager.variable_name');
35
36 9
        $view->with(
37 9
            is_string($variable)
38 9
                ? $variable
39 9
                : 'seo_manager',
40 9
            $this->seo_manager
41
        );
42
    }
43
44
    /**
45
     * Prepare the SEO tags for the view.
46
     *
47
     * @return mixed
48
     * @throws ShouldImplementSeoTagInterfaceException
49
     */
50 10
    protected function getSeoTags(): mixed
51
    {
52 10
        $model = call(
53 10
            config('seo-manager.model', SeoTag::class)
54
        );
55
56 10
        if (! $model->getInternal(Call::INSTANCE) instanceof SeoTagContract) {
57 1
            throw new ShouldImplementSeoTagInterfaceException();
58
        }
59
60 9
        $nonPrefixedUrl = request()->path();
61 9
        $url = Str::start($nonPrefixedUrl, '/');
62
63 9
        $instance = $model->where($model->getUrlColumnName(), $url)
64 9
            ->orWhere($model->getUrlColumnName(), $nonPrefixedUrl)
65 9
            ->first();
66
67 9
        if (is_null($instance)) {
68 3
            $instance = $model->whereIn($model->getUrlColumnName(), $this->wildcard($url))
69 3
                ->limit($this->getMaxWildcardLevels())
70 3
                ->get()
71 3
                ->sortByDesc(
72 3
                    fn ($entry) => strlen(
73 2
                        $entry->{$model->getUrlColumnName()}
74
                    )
75 3
                )->first();
76
        }
77
78 9
        return $instance?->{$model->getTagsColumnName()};
79
    }
80
81
    /**
82
     * Make the possible wildcards for the given path.
83
     *
84
     * @param string $url
85
     *
86
     * @return array
87
     */
88 3
    protected function wildcard(string $url): array
89
    {
90 3
        $separated = explode('/', $url);
91
92 3
        return collect($separated)
0 ignored issues
show
Bug introduced by
$separated of type string[] is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
        return collect(/** @scrutinizer ignore-type */ $separated)
Loading history...
93 3
            ->pipe(
94 3
                fn ($parts) => $parts->map(function ($value, $key) use ($parts) {
95 3
                    $wildcard = clone $parts->reject(
96 3
                        fn ($value, $rejection) => $key < $rejection
97 3
                    )->put($key, '*');
98
99 3
                    return $wildcard->implode('/');
100
                })
101 3
            )->toArray();
102
    }
103
104
    /**
105
     * Gets the levels to limit the query.
106
     *
107
     * @return mixed
108
     */
109 3
    private function getMaxWildcardLevels(): mixed
110
    {
111 3
        return config('seo-manager.max_wildcard_levels', 3);
112
    }
113
}
114