MenuRequest::isRelativeUrl()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 4
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Chief\App\Http\Requests;
4
5
use Illuminate\Foundation\Http\FormRequest;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Str;
8
use Thinktomorrow\Chief\Shared\Concerns\Translatable\TranslatableCommand;
9
use Thinktomorrow\Url\Root;
10
use Thinktomorrow\Url\Url;
11
12
class MenuRequest extends FormRequest
13
{
14
    use TranslatableCommand;
15
16
    /**
17
     * Determine if the user is authorized to make this request.
18
     *
19
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
20
     */
21
    public function authorize(): ?\Illuminate\Contracts\Auth\Authenticatable
22
    {
23
        return Auth::guard('chief')->user();
24
    }
25
26
    public function validationData()
27
    {
28
        $data = parent::validationData();
29
30
        $data = $this->sanitizeUrl($data);
31
32
        return $data;
33
    }
34
35
    /**
36
     * Get the validation rules that apply to the request.
37
     *
38
     * @return array
39
     */
40
    public function rules()
41
    {
42
        $translations = $this->request->all('trans');
43
44
        $rules['type'] = 'required|in:custom,internal,nolink';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$rules was never initialized. Although not strictly required by PHP, it is generally a good practice to add $rules = array(); before regardless.
Loading history...
45
        $rules['owner_reference'] = 'required_if:type,internal';
46
47
        foreach ($translations as $locale => $trans) {
48
            if ($this->isCompletelyEmpty(['label'], $trans) && $locale !== config('app.locale')) {
49
                continue;
50
            }
51
52
            $rules['trans.' . $locale . '.label'] = 'required';
53
            if ($this->request->get('trans.' . $locale . '.url') != null) {
54
                $rules['trans.' . $locale . '.url'] = 'url';
55
            }
56
        }
57
58
        return $rules;
59
    }
60
61
    public function attributes()
62
    {
63
        $attributes = [];
64
65
        foreach (array_keys($this->request->all('trans')) as $locale) {
66
            $attributes['trans.' . $locale . '.label'] = $locale . ' label';
67
            $attributes['trans.' . $locale . '.url'] = $locale . ' link';
68
        }
69
70
        $attributes['owner_reference'] = 'Interne pagina';
71
72
73
        return $attributes;
74
    }
75
76
    public function messages()
77
    {
78
        return [
79
            'required_if' => 'Gelieve nog een :attribute te kiezen, aub.',
80
            'required' => 'Gelieve een :attribute in te geven, aub.',
81
            'url' => 'Dit is geen geldige url. Kan je dit even nakijken, aub?',
82
        ];
83
    }
84
85
    /**
86
     * @param $data
87
     * @return mixed
88
     */
89
    protected function sanitizeUrl(array $data)
90
    {
91
        foreach ($data['trans'] as $locale => $trans) {
92
            if (empty($trans['url'])) {
93
                continue;
94
            }
95
96
            // Check if it is a relative
97
            if ($this->isRelativeUrl($trans['url'])) {
98
                $data['trans'][$locale]['url'] = '/' . trim($trans['url'], '/');
99
            } elseif (Str::startsWith($trans['url'], ['mailto:', 'tel:', 'https://', 'http://'])) {
100
                $data['trans'][$locale]['url'] = $trans['url'];
101
            } else {
102
                $data['trans'][$locale]['url'] = Url::fromString($trans['url'])->secure()->get();
103
            }
104
105
            $this->request->set('trans', $data['trans']);
106
        }
107
108
        return $data;
109
    }
110
111
    private function isRelativeUrl($url): bool
112
    {
113
        $nakedUrl = ltrim($url, '/');
114
115
        // Check if passed url is not intended as a host instead of a relative path
116
        $notIntentedAsRoot = (null == Root::fromString($url)->getScheme() && false === strpos($url, '.'));
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing Thinktomorrow\Url\Root::...ring($url)->getScheme() of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
117
118
        return ($notIntentedAsRoot && in_array($url, [$nakedUrl, '/' . $nakedUrl]));
119
    }
120
}
121