Passed
Push — master ( c3e4c9...e46620 )
by Aleksei
02:36 queued 45s
created

FileBucket::isInline()   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 0
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 0
b 0
f 0
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 8
    public function __construct($data, string $contentType = null, string $filename = null)
28
    {
29
        switch (true) {
30 8
            case $data instanceof SplFileInfo:
31
                $filename = $filename ?? $data->getFilename();
32
                $contentType = $contentType ?? $this->contentType($filename);
33
                parent::__construct($data);
34
                break;
35 8
            case is_string($data):
36
            case is_resource($data):
37 8
                parent::__construct($data);
38 8
                break;
39
            default:
40
                throw new \Exception('The $data parameter must be a resource, a string or an instance of SplFileInfo');
41
        }
42
43 8
        if ($contentType !== null) {
44
            $this->setContentType($contentType);
45
        }
46 8
        if ($filename !== null) {
47
            $this->setAttachment($filename);
48
        }
49 8
    }
50
51
    public static function createFromPath(string $filePath): self
52
    {
53
        return new static(new SplFileInfo($filePath));
54
    }
55
56 2
    public function getContentType(): ?string
57
    {
58 2
        return $this->contentType;
59
    }
60 1
    public function getFileName(): ?string
61
    {
62 1
        return $this->fileName;
63
    }
64 3
    public function hasDisposition(): bool
65
    {
66 3
        return $this->contentDisposition !== null;
67
    }
68 2
    public function isAttachment(): bool
69
    {
70 2
        return $this->contentDisposition === self::DISPOSITION_ATTACHMENT;
71
    }
72 2
    public function isInline(): bool
73
    {
74 2
        return $this->contentDisposition === self::DISPOSITION_INLINE;
75
    }
76
77 1
    public function withAttachment(string $filename = null): self
78
    {
79 1
        $clone = clone $this;
80 1
        $clone->setAttachment($filename);
81 1
        return $clone;
82
    }
83 1
    public function withContentType(?string $contentType): self
84
    {
85 1
        $clone = clone $this;
86 1
        $clone->setContentType($contentType);
87 1
        return $clone;
88
    }
89 1
    public function withInline(): self
90
    {
91 1
        $clone = clone $this;
92 1
        $clone->setInline();
93 1
        return $clone;
94
    }
95
96 1
    public function setContentType(?string $contentType): void
97
    {
98 1
        $this->contentType = $contentType;
99 1
        $this->setHeader(Header::CONTENT_TYPE, $contentType);
100 1
    }
101 1
    public function setInline(): void
102
    {
103 1
        $this->contentDisposition = self::DISPOSITION_INLINE;
104 1
        $this->setDispositionHeader();
105 1
    }
106 1
    final protected function setAttachment(?string $filename): void
107
    {
108 1
        $this->contentDisposition = self::DISPOSITION_ATTACHMENT;
109 1
        $this->fileName = $filename;
110 1
        $this->setDispositionHeader();
111 1
    }
112 2
    final protected function setDispositionHeader(): void
113
    {
114 2
        if ($this->contentDisposition === null) {
115
            return;
116
        }
117 2
        $headerBody = ($this->contentDisposition === self::DISPOSITION_ATTACHMENT && $this->fileName !== null)
118
            ? sprintf(
119
                '%s; filename="%s"; filename*=UTF-8\'\'%s',
120
                $this->contentDisposition,
121
                preg_replace('/[\x00-\x1F\x7F\"]/', ' ', $this->fileName),
122
                rawurlencode($this->fileName)
123
            )
124 2
            : $this->contentDisposition;
125 2
        $this->setHeader(Header::CONTENT_DISPOSITION, $headerBody);
126 2
    }
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