FileResponse::parseFilename()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 14
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DigitalCz\DigiSign\Stream;
6
7
use DigitalCz\DigiSign\Exception\RuntimeException;
8
use Psr\Http\Message\ResponseInterface;
9
10
/**
11
 * Wrapper class for file response
12
 */
13
final class FileResponse
14
{
15
    /** @var ResponseInterface  */
16
    private $response;
17
18
    /** @var FileStream  */
19
    private $file;
20
21
    public function __construct(ResponseInterface $response)
22
    {
23
        $this->response = $response;
24
    }
25
26
    public function getResponse(): ResponseInterface
27
    {
28
        return $this->response;
29
    }
30
31
    public function getFile(): FileStream
32
    {
33
        if (!isset($this->file)) {
34
            $body = $this->getResponse()->getBody();
35
            $handle = $body->detach();
36
37
            if ($handle === null) {
38
                throw new RuntimeException('Unable to get body handle');
39
            }
40
41
            $this->file = new FileStream($handle, $this->getContentLength(), $this->parseFilename());
42
        }
43
44
        return $this->file;
45
    }
46
47
    /**
48
     * @param string $path Path to directory or file
49
     */
50
    public function save(string $path): void
51
    {
52
        $this->getFile()->save($path);
53
    }
54
55
    private function parseFilename(): string
56
    {
57
        $contentDisposition = $this->getContentDisposition();
58
59
        // parse content-disposition header
60
        preg_match_all(
61
            "/filename[^;=\n]*=(?:(\\?['\"])(.*?)\1|(?:[^\s]+'.*?')?([^;\n]*))/i",
62
            $contentDisposition,
63
            $matches
64
        );
65
        end($matches[3]);
66
67
        // if there are multiple matches, return the last
68
        return $matches[3][key($matches[3])] ?? 'file';
69
    }
70
71
    private function getContentLength(): int
72
    {
73
        return (int)$this->getResponse()->getHeaderLine('Content-Length');
74
    }
75
76
    private function getContentDisposition(): string
77
    {
78
        return $this->getResponse()->getHeaderLine('Content-Disposition');
79
    }
80
}
81