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 (#4988)
by Cristian
27:47 queued 12:50
created

Uploader::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 9
nc 2
nop 2
dl 0
loc 13
rs 9.9666
c 1
b 0
f 1
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Uploads\Uploaders;
4
5
use Backpack\CRUD\app\Library\CrudPanel\Uploads\Interfaces\UploaderInterface;
6
use Backpack\CRUD\app\Library\CrudPanel\Uploads\Traits\HandleFileNaming;
7
use Backpack\CRUD\app\Library\CrudPanel\Uploads\Traits\HandleRepeatableUploads;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Database\Eloquent\SoftDeletes;
10
use Illuminate\Support\Facades\Storage;
11
use Illuminate\Support\Str;
12
13
abstract class Uploader implements UploaderInterface
14
{
15
    use HandleFileNaming;
16
    use HandleRepeatableUploads;
17
18
    /**
19
     * The name of the uploader AKA CrudField/Column name.
20
     *
21
     * @var string
22
     */
23
    private string $name;
24
25
    /**
26
     * Indicates the uploaded file should be deleted when entry is deleted.
27
     *
28
     * @var bool
29
     */
30
    private $deleteWhenEntryIsDeleted = true;
31
32
    /**
33
     * The disk where upload will be stored. By default `public`.
34
     *
35
     * @var string
36
     */
37
    private $disk = 'public';
38
39
    /**
40
     * Indicates if the upload handles multiple files.
41
     *
42
     * @var bool
43
     */
44
    private $isMultiple = false;
45
46
    /**
47
     * The path inside the disk to store the uploads.
48
     *
49
     * @var string
50
     */
51
    private $path = '';
52
53
    /**
54
     * Should the url to the object be a temporary one (eg: s3).
55
     *
56
     * @var bool
57
     */
58
    private $useTemporaryUrl = false;
59
60
    /**
61
     * When using temporary urls, defines the time that the url
62
     * should be available in minutes.
63
     *
64
     * By default 1 minute
65
     *
66
     * @var int
67
     */
68
    private $temporaryUrlExpirationTime = 1;
69
70
    /**
71
     * Indicates if the upload is relative to a relationship field/column.
72
     *
73
     * @var bool
74
     */
75
    private $isRelationship = false;
76
77
    final public function __construct(array $crudObject, array $configuration)
78
    {
79
        $this->name = $crudObject['name'];
80
        $this->disk = $configuration['disk'] ?? $crudObject['disk'] ?? $this->disk;
81
        $this->useTemporaryUrl = $configuration['temporary'] ?? $this->useTemporaryUrl;
82
        $this->temporaryUrlExpirationTime = $configuration['expiration'] ?? $this->temporaryUrlExpirationTime;
83
        $this->deleteWhenEntryIsDeleted = $configuration['whenDelete'] ?? $this->deleteWhenEntryIsDeleted;
84
85
        $this->path = $configuration['path'] ?? $crudObject['prefix'] ?? $this->path;
86
        $this->path = empty($this->path) ? $this->path : Str::of($this->path)->finish('/')->value();
87
88
        $this->setFileNameGenerator($configuration['fileNameGenerator'] ?? null);
89
        $this->fileName = $configuration['fileName'] ?? $this->fileName;
90
    }
91
92
    /**
93
     * An abstract function that all uploaders must implement for a single file save process.
94
     *
95
     * @param  Model  $entry
96
     * @param  mixed  $values
97
     * @return mixed
98
     */
99
    abstract public function uploadFile(Model $entry, $values = null);
100
101
    /**
102
     * The function called in the saving event that starts the upload process.
103
     *
104
     * @param  Model  $entry
105
     * @return Model
106
     */
107
    public function processFileUpload(Model $entry)
108
    {
109
        if ($this->isRepeatable) {
110
            return $this->handleRepeatableFiles($entry);
111
        }
112
113
        $entry->{$this->name} = $this->uploadFile($entry);
114
115
        return $entry;
116
    }
117
118
    /**
119
     * Return the uploader name.
120
     *
121
     * @return string
122
     */
123
    public function getName()
124
    {
125
        return $this->name;
126
    }
127
128
    /**
129
     * Return the uploader disk.
130
     *
131
     * @return string
132
     */
133
    public function getDisk()
134
    {
135
        return $this->disk;
136
    }
137
138
    /**
139
     * Return the uploader path.
140
     *
141
     * @return string
142
     */
143
    public function getPath()
144
    {
145
        return $this->path;
146
    }
147
148
    /**
149
     * Return the uploader temporary option.
150
     *
151
     * @return bool
152
     */
153
    public function getTemporary()
154
    {
155
        return $this->useTemporaryUrl;
156
    }
157
158
    /**
159
     * Return the uploader expiration time in minutes.
160
     *
161
     * @return int
162
     */
163
    public function getExpiration()
164
    {
165
        return $this->temporaryUrlExpirationTime;
166
    }
167
168
    /**
169
     * The function called in the retrieved event that handles the display of uploaded values.
170
     *
171
     * @param  Model  $entry
172
     * @return Model
173
     */
174
    public function retrieveUploadedFile(Model $entry)
175
    {
176
        if ($this->isRepeatable) {
177
            return $this->retrieveRepeatableFiles($entry);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->retrieveRepeatableFiles($entry) returns the type void which is incompatible with the documented return type Illuminate\Database\Eloquent\Model.
Loading history...
Bug introduced by
Are you sure the usage of $this->retrieveRepeatableFiles($entry) targeting Backpack\CRUD\app\Librar...trieveRepeatableFiles() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
178
        }
179
180
        return $this->retrieveFile($entry);
181
    }
182
183
    protected function retrieveFile($entry)
184
    {
185
        $value = $entry->{$this->name};
186
187
        if ($this->isMultiple && ! isset($entry->getCasts()[$this->name]) && is_string($value)) {
188
            $entry->{$this->name} = json_decode($value, true);
189
        } else {
190
            $entry->{$this->name} = Str::after($value, $this->path);
191
        }
192
193
        return $entry;
194
    }
195
196
    /**
197
     * The function called in the deleting event. It checks if the uploaded file should be deleted.
198
     *
199
     * @param  Model  $entry
200
     * @return void
201
     */
202
    public function deleteUploadedFile(Model $entry)
203
    {
204
        if ($this->deleteWhenEntryIsDeleted) {
205
            if (! in_array(SoftDeletes::class, class_uses_recursive($entry), true)) {
206
                $this->performFileDeletion($entry);
207
208
                return;
209
            }
210
211
            if ($entry->isForceDeleting() === true) {
212
                $this->performFileDeletion($entry);
213
            }
214
        }
215
    }
216
217
    /**
218
     * The function called in the retrieved event that handles the display of uploaded values.
219
     *
220
     * @param  Model  $entry
221
     * @return void
222
     */
223
    private function deleteFiles($entry)
224
    {
225
        $values = $entry->{$this->name};
226
227
        if ($this->isMultiple) {
228
            if (! isset($entry->getCasts()[$this->name]) && is_string($values)) {
229
                $values = json_decode($values, true);
230
            }
231
        } else {
232
            $values = (array) Str::after($values, $this->path);
233
        }
234
235
        foreach ($values as $value) {
236
            Storage::disk($this->disk)->delete($this->path.$value);
237
        }
238
    }
239
240
    /**
241
     * When the file should be deleted, this function is called to delete the file using the
242
     * appropriate delete method depending on some uploader properties.
243
     *
244
     * @param  Model  $entry
245
     * @return void
246
     */
247
    private function performFileDeletion($entry)
248
    {
249
        if ($this->isRelationship || ! $this->isRepeatable) {
250
            $this->deleteFiles($entry);
251
252
            return;
253
        }
254
255
        $this->deleteRepeatableFiles($entry);
256
    }
257
258
    /**
259
     * Build an uploader instance.
260
     *
261
     * @param  array  $crudObject
262
     * @param  array  $definition
263
     * @return self
264
     */
265
    public static function for(array $crudObject, array $definition)
266
    {
267
        return new static($crudObject, $definition);
268
    }
269
270
    /**
271
     * Set multiple attribute to true in the uploader.
272
     *
273
     * @return self
274
     */
275
    protected function multiple()
276
    {
277
        $this->isMultiple = true;
278
279
        return $this;
280
    }
281
282
    /**
283
     * Set relationship attribute in uploader.
284
     * When true, it also removes the repeatable in case the relationship is handled.
285
     *
286
     * @param  bool  $isRelationship
287
     * @return self
288
     */
289
    public function relationship(bool $isRelationship): self
290
    {
291
        $this->isRelationship = $isRelationship;
292
293
        return $this;
294
    }
295
296
    /**
297
     * Should the files be deleted when the entry is deleted.
298
     *
299
     * @return bool
300
     */
301
    public function shouldDeleteFiles()
302
    {
303
        return $this->deleteWhenEntryIsDeleted;
304
    }
305
306
    public function getIdentifier()
307
    {
308
        if ($this->isRepeatable) {
309
            return $this->repeatableContainerName.'_'.$this->name;
310
        }
311
312
        return $this->name;
313
    }
314
}
315