Passed
Push — master ( 32fc02...88ceb8 )
by Aleksei
02:03
created

FileBucket::getContentType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 1
f 1
1
<?php
2
3
namespace roxblnfk\SmartStream\Data;
4
5
use SplFileInfo;
6
use Yiisoft\Http\Header;
7
8
class FileBucket extends DataBucket
9
{
10
    public const TYPE_OCTET_STREAM = 'application/octet-stream';
11
12
    protected const DISPOSITION_INLINE = 'inline';
13
    protected const DISPOSITION_ATTACHMENT = 'attachment';
14
15
    protected const IS_CONVERTABLE = false;
16
    protected ?string $contentType = null;
17
    protected ?string $contentDisposition = null;
18
    protected ?string $fileName = null;
19
20
    /**
21
     * FileBucket constructor.
22
     * @param string|resource|SplFileInfo $data
23
     * @param null|string $contentType
24
     * @param null|string $filename
25
     * @throws \Exception
26
     */
27 27
    public function __construct($data, string $contentType = null, string $filename = null)
28
    {
29
        switch (true) {
30 27
            case $data instanceof SplFileInfo:
31
                $filename = $filename ?? $data->getFilename();
32
                $contentType = $contentType ?? $this->contentType($filename);
33
                parent::__construct($data);
34
                break;
35 27
            case is_string($data):
36
            case is_resource($data):
37 27
                parent::__construct($data);
38 27
                break;
39
            default:
40
                throw new \Exception('The $data parameter must be a resource, a string or an instance of SplFileInfo');
41
        }
42
43 27
        if ($contentType !== null) {
44
            $this->setContentType($contentType);
45
        }
46 27
        if ($filename !== null) {
47
            $this->setAttachment($filename);
48
        }
49 27
    }
50
51
    public static function createFromPath(string $filePath): self
52
    {
53
        return new static(new SplFileInfo($filePath));
54
    }
55
56 4
    public function getContentType(): ?string
57
    {
58 4
        return $this->contentType;
59
    }
60 3
    public function getFileName(): ?string
61
    {
62 3
        return $this->fileName;
63
    }
64 3
    public function hasDisposition(): bool
65
    {
66 3
        return $this->contentDisposition !== null;
67
    }
68 6
    public function isAttachment(): bool
69
    {
70 6
        return $this->contentDisposition === self::DISPOSITION_ATTACHMENT;
71
    }
72 4
    public function isInline(): bool
73
    {
74 4
        return $this->contentDisposition === self::DISPOSITION_INLINE;
75
    }
76
77 14
    public function withAttachment(string $filename = null): self
78
    {
79 14
        $clone = clone $this;
80 14
        $clone->setAttachment($filename);
81 14
        return $clone;
82
    }
83 3
    public function withContentType(?string $contentType): self
84
    {
85 3
        $clone = clone $this;
86 3
        $clone->setContentType($contentType);
87 3
        return $clone;
88
    }
89 4
    public function withInline(): self
90
    {
91 4
        $clone = clone $this;
92 4
        $clone->setInline();
93 4
        return $clone;
94
    }
95
96 3
    public function setContentType(?string $contentType): void
97
    {
98 3
        $this->contentType = $contentType;
99 3
        $this->setHeader(Header::CONTENT_TYPE, $contentType);
100 3
    }
101 4
    public function setInline(): void
102
    {
103 4
        $this->contentDisposition = self::DISPOSITION_INLINE;
104 4
        $this->setDispositionHeader();
105 4
    }
106 14
    final protected function setAttachment(?string $filename): void
107
    {
108 14
        $this->contentDisposition = self::DISPOSITION_ATTACHMENT;
109 14
        $this->fileName = $filename;
110 14
        $this->setDispositionHeader();
111 14
    }
112 16
    final protected function setDispositionHeader(): void
113
    {
114 16
        if ($this->contentDisposition === null) {
115
            return;
116
        }
117 16
        $headerBody = ($this->contentDisposition === self::DISPOSITION_ATTACHMENT && $this->fileName !== null)
118 10
            ? sprintf(
119 10
                '%s; filename="%s"; filename*=UTF-8\'\'%s',
120 10
                $this->contentDisposition,
121 10
                preg_replace('/[\x00-\x1F\x7F\"]/', ' ', $this->fileName),
122 10
                rawurlencode($this->fileName)
123
            )
124 16
            : $this->contentDisposition;
125 16
        $this->setHeader(Header::CONTENT_DISPOSITION, $headerBody);
126 16
    }
127
    private function contentType(?string $filename): ?string
128
    {
129
        if ($filename === null) {
130
            return null;
131
        }
132
        $result = function_exists('mime_content_type') ? mime_content_type($filename) : null;
133
        return is_string($result) ? $result : null;
134
    }
135
}
136