Passed
Push — master ( 335552...de70eb )
by László
03:52
created

BlueimpHandler::download()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2.0094

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 13
cts 15
cp 0.8667
rs 9.488
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2.0094
1
<?php
2
3
namespace CodingSocks\UploadHandler\Driver;
4
5
use Closure;
6
use CodingSocks\UploadHandler\Helper\ChunkHelpers;
7
use CodingSocks\UploadHandler\Identifier\Identifier;
8
use CodingSocks\UploadHandler\Range\ContentRange;
9
use CodingSocks\UploadHandler\Response\PercentageJsonResponse;
10
use CodingSocks\UploadHandler\StorageConfig;
11
use Illuminate\Http\JsonResponse;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Arr;
14
use Illuminate\Support\Str;
15
use InvalidArgumentException;
16
use Symfony\Component\HttpFoundation\Response;
17
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
18
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
19
20
class BlueimpHandler extends BaseHandler
21
{
22 1
    use ChunkHelpers;
23
24
    /**
25
     * @var string
26
     */
27
    private $fileParam;
28
29
    /**
30
     * @var \CodingSocks\UploadHandler\Identifier\Identifier
31
     */
32
    private $identifier;
33
34
    /**
35
     * BlueimpDriver constructor.
36
     *
37
     * @param array $config
38
     * @param \CodingSocks\UploadHandler\Identifier\Identifier $identifier
39
     */
40 14
    public function __construct($config, Identifier $identifier)
41
    {
42 14
        $this->fileParam = $config['param'];
43 14
        $this->identifier = $identifier;
44 14
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49 12
    public function handle(Request $request, StorageConfig $config, Closure $fileUploaded = null): Response
50
    {
51 12
        if ($this->isRequestMethodIn($request, [Request::METHOD_HEAD, Request::METHOD_OPTIONS])) {
52 1
            return $this->info();
53
        }
54
55 11
        if ($this->isRequestMethodIn($request, [Request::METHOD_GET])) {
56 1
            return $this->download($request, $config);
57
        }
58
59 10
        if ($this->isRequestMethodIn($request, [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH])) {
60 6
            return $this->save($request, $config, $fileUploaded);
61
        }
62
63 4
        throw new MethodNotAllowedHttpException([
64 4
            Request::METHOD_HEAD,
65
            Request::METHOD_OPTIONS,
66
            Request::METHOD_GET,
67
            Request::METHOD_POST,
68
            Request::METHOD_PUT,
69
            Request::METHOD_PATCH,
70
        ]);
71
    }
72
73
    /**
74
     * @return \Symfony\Component\HttpFoundation\Response
75
     */
76 1
    public function info(): Response
77
    {
78 1
        return new JsonResponse([], Response::HTTP_OK, [
79 1
            'Pragma' => 'no-cache',
80
            'Cache-Control' => 'no-store, no-cache, must-revalidate',
81
            'Content-Disposition' => 'inline; filename="files.json"',
82
            'X-Content-Type-Options' => 'nosniff',
83
            'Vary' => 'Accept',
84
        ]);
85
    }
86
87
    /**
88
     * @param \Illuminate\Http\Request $request
89
     * @param \CodingSocks\UploadHandler\StorageConfig $config
90
     *
91
     * @return \Symfony\Component\HttpFoundation\Response
92
     */
93 1
    public function download(Request $request, StorageConfig $config): Response
94
    {
95 1
        $request->validate([
0 ignored issues
show
Bug introduced by
The call to validate() misses a required argument $...$params.

This check looks for function calls that miss required arguments.

Loading history...
96 1
            $this->fileParam => 'required',
97 1
            'totalSize' => 'required',
98
        ]);
99
100 1
        $originalFilename = $request->query($this->fileParam);
101 1
        $totalSize = $request->query('totalSize');
102 1
        $uid = $this->identifier->generateFileIdentifier($totalSize, $originalFilename);
0 ignored issues
show
Documentation introduced by
$totalSize is of type string|array|null, but the function expects a double.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $originalFilename defined by $request->query($this->fileParam) on line 100 can also be of type array or null; however, CodingSocks\UploadHandle...enerateFileIdentifier() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
103
104 1
        if (!$this->chunkExists($config, $uid)) {
105
            return new JsonResponse([
106
                'file' => null,
107
            ]);
108
        }
109
110 1
        $chunk = Arr::last($this->chunks($config, $uid));
111 1
        $size = explode('-', basename($chunk))[1] + 1;
112
113 1
        return new JsonResponse([
114
            'file' => [
115 1
                'name' => $originalFilename,
116 1
                'size' => $size,
117
            ],
118
        ]);
119
    }
120
121
    /**
122
     * @param \Illuminate\Http\Request $request
123
     * @param \CodingSocks\UploadHandler\StorageConfig $config
124
     * @param \Closure|null $fileUploaded
125
     *
126
     * @return \Symfony\Component\HttpFoundation\Response
127
     */
128 6
    public function save(Request $request, StorageConfig $config, Closure $fileUploaded = null): Response
129
    {
130 6
        $file = $request->file($this->fileParam);
131
132 6
        if (null === $file) {
133 1
            $file = Arr::first($request->file(Str::plural($this->fileParam), []));
0 ignored issues
show
Documentation introduced by
$request->file(\Illumina...s->fileParam), array()) is of type object<Illuminate\Http\UploadedFile>|array|null, but the function expects a object<Illuminate\Support\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
134
        }
135
136 6
        $this->validateUploadedFile($file);
137
138
        try {
139 4
            $range = new ContentRange($request->headers);
140
        } catch (InvalidArgumentException $e) {
141
            throw new BadRequestHttpException($e->getMessage(), $e);
142
        }
143
144 4
        $uid = $this->identifier->generateFileIdentifier($range->getTotal(), $file->getClientOriginalName());
145
146 4
        $chunks = $this->storeChunk($config, $range, $file, $uid);
147
148 4
        if (!$range->isLast()) {
149 2
            return new PercentageJsonResponse($range->getPercentage());
150
        }
151
152 2
        $targetFilename = $file->hashName();
153
154 2
        $path = $this->mergeChunks($config, $chunks, $targetFilename);
155
156 2
        if ($config->sweep()) {
157
            $this->deleteChunkDirectory($config, $uid);
158
        }
159
160 2
        $this->triggerFileUploadedEvent($config->getDisk(), $path, $fileUploaded);
161
162 2
        return new PercentageJsonResponse(100);
163
    }
164
}
165