Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Test Failed
Pull Request — main (#5518)
by Pedro
34:25 queued 23:25
created

UploadersRepository::isValidUploadField()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 12
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Library\Uploaders\Support;
4
5
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
6
use Backpack\CRUD\app\Library\Uploaders\Support\Interfaces\UploaderInterface;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Str;
9
10
final class UploadersRepository
11
{
12
    /**
13
     * The array of uploaders classes for field types.
14
     */
15
    private array $uploaderClasses;
16
17
    /**
18
     * Uploaders registered in a repeatable group.
19
     */
20
    private array $repeatableUploaders = [];
21
22
    /**
23
     * Uploaders that have already been handled (events registered) for each field/column instance.
24
     */
25
    private array $handledUploaders = [];
26
27
    public function __construct()
28
    {
29
        $this->uploaderClasses = config('backpack.crud.uploaders');
30
    }
31
32
    /**
33
     * Mark the given uploader as handled.
34
     */
35
    public function markAsHandled(string $objectName): void
36
    {
37
        if (! in_array($objectName, $this->handledUploaders)) {
38
            $this->handledUploaders[] = $objectName;
39
        }
40
    }
41
42
    /**
43
     * Check if the given uploader for field/column have been handled.
44
     */
45
    public function isUploadHandled(string $objectName): bool
46
    {
47
        return in_array($objectName, $this->handledUploaders);
48
    }
49
50
    /**
51
     * Check if there are uploads for the give object(field/column) type.
52
     */
53
    public function hasUploadFor(string $objectType, string $group): bool
54
    {
55
        return array_key_exists($objectType, $this->uploaderClasses[$group]);
56
    }
57
58
    /**
59
     * Return the uploader for the given object type.
60
     */
61
    public function getUploadFor(string $objectType, string $group): string
62
    {
63
        return $this->uploaderClasses[$group][$objectType];
64
    }
65
66
    /**
67
     * Register new uploaders or override existing ones.
68
     */
69
    public function addUploaderClasses(array $uploaders, string $group): void
70
    {
71
        $this->uploaderClasses[$group] = array_merge($this->getGroupUploadersClasses($group), $uploaders);
72
    }
73
74
    /**
75
     * Return the uploaders classes for the given group.
76
     */
77
    private function getGroupUploadersClasses(string $group): array
78
    {
79
        return $this->uploaderClasses[$group] ?? [];
80
    }
81
82
    /**
83
     * Register the specified uploader for the given upload name.
84
     */
85
    public function registerRepeatableUploader(string $uploadName, UploaderInterface $uploader): void
86
    {
87
        if (! array_key_exists($uploadName, $this->repeatableUploaders) || ! in_array($uploader, $this->repeatableUploaders[$uploadName])) {
88
            $this->repeatableUploaders[$uploadName][] = $uploader;
89
        }
90
    }
91
92
    /**
93
     * Check if there are uploaders registered for the given upload name.
94
     */
95
    public function hasRepeatableUploadersFor(string $uploadName): bool
96
    {
97
        return array_key_exists($uploadName, $this->repeatableUploaders);
98
    }
99
100
    /**
101
     * Get the repeatable uploaders for the given upload name.
102
     */
103
    public function getRepeatableUploadersFor(string $uploadName): array
104
    {
105
        return $this->repeatableUploaders[$uploadName] ?? [];
106
    }
107
108
    /**
109
     * Check if the specified upload is registered for the given repeatable uploads.
110
     */
111
    public function isUploadRegistered(string $uploadName, UploaderInterface $upload): bool
112
    {
113
        return $this->hasRepeatableUploadersFor($uploadName) && in_array($upload->getName(), $this->getRegisteredUploadNames($uploadName));
114
    }
115
116
    /**
117
     * Return the registered uploaders names for the given repeatable upload name.
118
     */
119
    public function getRegisteredUploadNames(string $uploadName): array
120
    {
121
        return array_map(function ($uploader) {
122
            return $uploader->getName();
123
        }, $this->getRepeatableUploadersFor($uploadName));
124
    }
125
126
    /**
127
     * Get the uploaders classes for the given group of uploaders.
128
     */
129
    public function getAjaxUploadTypes(string $uploaderMacro = 'withFiles'): array
130
    {
131
        $ajaxFieldTypes = [];
132
        foreach ($this->uploaderClasses[$uploaderMacro] as $fieldType => $uploader) {
133
            if (is_a($uploader, 'Backpack\Pro\Uploads\BackpackAjaxUploader', true)) {
134
                $ajaxFieldTypes[] = $fieldType;
135
            }
136
        }
137
138
        return $ajaxFieldTypes;
139
    }
140
141
    /**
142
     * Get an ajax uploader instance for a given input name.
143
     */
144
    public function getFieldUploaderInstance(string $requestInputName): UploaderInterface
145
    {
146
        if (strpos($requestInputName, '#') !== false) {
147
            $repeatableContainerName = Str::before($requestInputName, '#');
148
            $requestInputName = Str::after($requestInputName, '#');
149
150
            $uploaders = $this->getRepeatableUploadersFor($repeatableContainerName);
151
152
            $uploader = Arr::first($uploaders, function ($uploader) use ($requestInputName) {
153
                return $uploader->getName() === $requestInputName;
154
            });
155
156
            if (! $uploader) {
157
                abort(500, 'Could not find the field in the repeatable uploaders.');
158
            }
159
160
            return $uploader;
161
        }
162
163
        if (empty($crudObject = CRUD::fields()[$requestInputName])) {
0 ignored issues
show
Bug introduced by
The method fields() does not exist on Backpack\CRUD\app\Librar...udPanel\CrudPanelFacade. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

163
        if (empty($crudObject = CRUD::/** @scrutinizer ignore-call */ fields()[$requestInputName])) {
Loading history...
164
            abort(500, 'Could not find the field in the CRUD fields.');
165
        }
166
167
        if (! $uploaderMacro = $this->getUploadCrudObjectMacroType($crudObject)) {
168
            abort(500, 'There is no uploader defined for the given field type.');
169
        }
170
171
        if (! $this->isValidUploadField($crudObject, $uploaderMacro)) {
172
            abort(500, 'Invalid field for upload.');
173
        }
174
175
        $uploaderConfiguration = $crudObject[$uploaderMacro] ?? [];
176
        $uploaderConfiguration = ! is_array($uploaderConfiguration) ? [] : $uploaderConfiguration;
177
        $uploaderClass = $this->getUploadFor($crudObject['type'], $uploaderMacro);
178
179
        return new $uploaderClass(['name' => $requestInputName], $uploaderConfiguration);
180
    }
181
182
    /**
183
     * Get the upload field macro type for the given object.
184
     */
185
    private function getUploadCrudObjectMacroType(array $crudObject): string|null
186
    {
187
        return isset($crudObject['withFiles']) ? 'withFiles' : (isset($crudObject['withMedia']) ? 'withMedia' : null);
188
    }
189
190
    private function isValidUploadField($crudObject, $uploaderMacro)
191
    {
192
        if (Str::contains($crudObject['name'], '#')) {
193
            $container = Str::before($crudObject['name'], '#');
194
            $field = array_filter(CRUD::fields()[$container]['subfields'] ?? [], function ($item) use ($crudObject, $uploaderMacro) {
195
                return $item['name'] === $crudObject['name'] && in_array($item['type'], $this->getAjaxUploadTypes($uploaderMacro));
196
            });
197
198
            return ! empty($field);
199
        }
200
201
        return in_array($crudObject['type'], $this->getAjaxUploadTypes($uploaderMacro));
202
    }
203
}
204