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

Passed
Pull Request — main (#5440)
by Cristian
30:05 queued 14:48
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\Str;
8
9
final class UploadersRepository
10
{
11
    /**
12
     * The array of uploaders classes for field types.
13
     */
14
    private array $uploaderClasses;
15
16
    /**
17
     * Uploaders registered in a repeatable group.
18
     */
19
    private array $repeatableUploaders = [];
20
21
    /**
22
     * Uploaders that have already been handled (events registered) for each field/column instance.
23
     */
24
    private array $handledUploaders = [];
25
26
    public function __construct()
27
    {
28
        $this->uploaderClasses = config('backpack.crud.uploaders');
29
    }
30
31
    /**
32
     * Mark the given uploader as handled.
33
     */
34
    public function markAsHandled(string $objectName): void
35
    {
36
        if (! in_array($objectName, $this->handledUploaders)) {
37
            $this->handledUploaders[] = $objectName;
38
        }
39
    }
40
41
    /**
42
     * Check if the given uploader for field/column have been handled.
43
     */
44
    public function isUploadHandled(string $objectName): bool
45
    {
46
        return in_array($objectName, $this->handledUploaders);
47
    }
48
49
    /**
50
     * Check if there are uploads for the give object(field/column) type.
51
     */
52
    public function hasUploadFor(string $objectType, string $group): bool
53
    {
54
        return array_key_exists($objectType, $this->uploaderClasses[$group]);
55
    }
56
57
    /**
58
     * Return the uploader for the given object type.
59
     */
60
    public function getUploadFor(string $objectType, string $group): string
61
    {
62
        return $this->uploaderClasses[$group][$objectType];
63
    }
64
65
    /**
66
     * Register new uploaders or override existing ones.
67
     */
68
    public function addUploaderClasses(array $uploaders, string $group): void
69
    {
70
        $this->uploaderClasses[$group] = array_merge($this->getGroupUploadersClasses($group), $uploaders);
71
    }
72
73
    /**
74
     * Return the uploaders classes for the given group.
75
     */
76
    private function getGroupUploadersClasses(string $group): array
77
    {
78
        return $this->uploaderClasses[$group] ?? [];
79
    }
80
81
    /**
82
     * Register the specified uploader for the given upload name.
83
     */
84
    public function registerRepeatableUploader(string $uploadName, UploaderInterface $uploader): void
85
    {
86
        if (! array_key_exists($uploadName, $this->repeatableUploaders) || ! in_array($uploader, $this->repeatableUploaders[$uploadName])) {
87
            $this->repeatableUploaders[$uploadName][] = $uploader;
88
        }
89
    }
90
91
    /**
92
     * Check if there are uploaders registered for the given upload name.
93
     */
94
    public function hasRepeatableUploadersFor(string $uploadName): bool
95
    {
96
        return array_key_exists($uploadName, $this->repeatableUploaders);
97
    }
98
99
    /**
100
     * Get the repeatable uploaders for the given upload name.
101
     */
102
    public function getRepeatableUploadersFor(string $uploadName): array
103
    {
104
        return $this->repeatableUploaders[$uploadName] ?? [];
105
    }
106
107
    /**
108
     * Check if the specified upload is registered for the given repeatable uploads.
109
     */
110
    public function isUploadRegistered(string $uploadName, UploaderInterface $upload): bool
111
    {
112
        return $this->hasRepeatableUploadersFor($uploadName) && in_array($upload->getName(), $this->getRegisteredUploadNames($uploadName));
113
    }
114
115
    /**
116
     * Return the registered uploaders names for the given repeatable upload name.
117
     */
118
    public function getRegisteredUploadNames(string $uploadName): array
119
    {
120
        return array_map(function ($uploader) {
121
            return $uploader->getName();
122
        }, $this->getRepeatableUploadersFor($uploadName));
123
    }
124
125
    /**
126
     * Get the uploaders classes for the given group of uploaders.
127
     */
128
    public function getAjaxUploadTypes(string $uploaderMacro = 'withFiles'): array
129
    {
130
        $ajaxFieldTypes = [];
131
        foreach ($this->uploaderClasses[$uploaderMacro] as $fieldType => $uploader) {
132
            if (is_a($uploader, 'Backpack\Pro\Uploads\BackpackAjaxUploader', true)) {
133
                $ajaxFieldTypes[] = $fieldType;
134
            }
135
        }
136
137
        return $ajaxFieldTypes;
138
    }
139
140
    /**
141
     * Get an uploader instance for a given crud object.
142
     */
143
    public function getFieldUploaderInstance(string $requestInputName): UploaderInterface
144
    {
145
        if (strpos($requestInputName, '#') !== false) {
146
            $repeatableContainerName = Str::before($requestInputName, '#');
147
            $requestInputName = Str::after($requestInputName, '#');
148
            $uploaders = $this->getRepeatableUploadersFor($repeatableContainerName);
0 ignored issues
show
Unused Code introduced by
The assignment to $uploaders is dead and can be removed.
Loading history...
149
            //TODO: Implement the logic for repeatable uploaders
150
            dd('here');
151
        }
152
153
        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

153
        if (empty($crudObject = CRUD::/** @scrutinizer ignore-call */ fields()[$requestInputName])) {
Loading history...
154
            abort(500, 'Could not find the field in the CRUD fields.');
155
        }
156
157
        if (! $uploaderMacro = $this->getUploadCrudObjectMacroType($crudObject)) {
158
            abort(500, 'There is no uploader defined for the given field type.');
159
        }
160
161
        if (! $this->isValidUploadField($crudObject, $uploaderMacro)) {
162
            abort(500, 'Invalid field for upload.');
163
        }
164
165
        $uploaderConfiguration = $crudObject[$uploaderMacro] ?? [];
166
        $uploaderConfiguration = ! is_array($uploaderConfiguration) ? [] : $uploaderConfiguration;
167
        $uploaderClass = $this->getUploadFor($crudObject['type'], $uploaderMacro);
168
169
        return new $uploaderClass(['name' => $requestInputName], $uploaderConfiguration);
170
    }
171
172
    /**
173
     * Get the upload field macro type for the given object.
174
     */
175
    private function getUploadCrudObjectMacroType(array $crudObject): string
176
    {
177
        return isset($crudObject['withFiles']) ? 'withFiles' : ($crudObject['withMedia'] ? 'withMedia' : null);
0 ignored issues
show
Bug Best Practice introduced by
The expression return IssetNode ? 'with...'] ? 'withMedia' : null could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
178
    }
179
180
    private function isValidUploadField($crudObject, $uploaderMacro)
181
    {
182
        if (Str::contains($crudObject['name'], '#')) {
183
            $container = Str::before($crudObject['name'], '#');
184
            $field = array_filter(CRUD::fields()[$container]['subfields'] ?? [], function ($item) use ($crudObject, $uploaderMacro) {
185
                return $item['name'] === $crudObject['name'] && in_array($item['type'], $this->getAjaxUploadTypes($uploaderMacro));
186
            });
187
188
            return ! empty($field);
189
        }
190
191
        return in_array($crudObject['type'], $this->getAjaxUploadTypes($uploaderMacro));
192
    }
193
}
194