Passed
Push — master ( e99d7d...a203c5 )
by Petr
02:39
created

VolumeObject::getPart()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 30
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 16
nop 3
dl 0
loc 30
rs 8.6346
c 0
b 0
f 0
1
<?php
2
3
namespace kalanis\UploadPerPartes\DataStorage;
4
5
6
use kalanis\UploadPerPartes\Exceptions\UploadException;
7
use RuntimeException;
8
use SplFileObject;
9
10
11
/**
12
 * Class VolumeBasic
13
 * @package kalanis\UploadPerPartes\DataStorage
14
 * Processing info file on disk volume
15
 * Filesystem behaves oddly - beware of fucked up caching!
16
 * When someone got idea how to test it without ignoring failed states, please tell me.
17
 * DO NOT TEST THIS WITH UNIT TESTS!
18
 */
19
class VolumeObject extends VolumeBasic
20
{
21
    /**
22
     * @param string $location
23
     * @param string $content
24
     * @param int<0, max>|null $seek
25
     * @throws UploadException
26
     * @codeCoverageIgnore
27
     */
28
    public function addPart(string $location, string $content, ?int $seek = null): void
29
    {
30
        $file = new SplFileObject($location, 'rb+');
31
        if (false === @$file->ftell()) {
32
            throw new UploadException($this->lang->uppCannotOpenFile($location));
33
        }
34
        $position = is_null($seek) ? @$file->fseek(0, SEEK_END) : @$file->fseek($seek) ;
35
        if ($position == -1) {
36
            unset($file);
37
            throw new UploadException($this->lang->uppCannotSeekFile($location));
38
        }
39
        $status = @$file->fwrite($content);
40
        if (false === $status || is_null($status)) { /** @phpstan-ignore-line probably bug in phpstan definitions */
41
            unset($file);
42
            throw new UploadException($this->lang->uppCannotWriteFile($location));
43
        }
44
        unset($file);
45
    }
46
47
    /**
48
     * @param string $location
49
     * @param int<0, max> $offset
50
     * @param int<0, max>|null $limit
51
     * @return string
52
     * @throws UploadException
53
     * @codeCoverageIgnore
54
     */
55
    public function getPart(string $location, int $offset, ?int $limit = null): string
56
    {
57
        try {
58
            $file = new SplFileObject($location, 'rb+');
59
            if (false === @$file->ftell()) {
60
                throw new UploadException($this->lang->uppCannotOpenFile($location));
61
            }
62
            if (empty($limit)) {
63
                $position = @$file->fseek(0, SEEK_END);
64
                if ($position == -1) {
65
                    unset($file);
66
                    throw new UploadException($this->lang->uppCannotSeekFile($location));
67
                }
68
                $limit = @$file->ftell() - $offset;
69
            }
70
            $position = @$file->fseek($offset, SEEK_SET);
71
            if ($position == -1) {
72
                unset($file);
73
                throw new UploadException($this->lang->uppCannotSeekFile($location));
74
            }
75
            $data = @$file->fread(intval($limit));
76
77
            if (false === $data) {
78
                unset($file);
79
                throw new UploadException($this->lang->uppCannotReadFile($location));
80
            }
81
            unset($file);
82
            return $data;
83
        } catch (RuntimeException $ex) {
84
            throw new UploadException($this->lang->uppCannotReadFile($location), 0, $ex);
85
        }
86
    }
87
88
    /**
89
     * @param string $location
90
     * @param int<0, max> $offset
91
     * @throws UploadException
92
     * @codeCoverageIgnore
93
     */
94
    public function truncate(string $location, int $offset): void
95
    {
96
        try {
97
            $file = new SplFileObject($location, 'rb+');
98
            $file->rewind();
99
            if (!$file->ftruncate($offset)) {
100
                unset($file);
101
                throw new UploadException($this->lang->uppCannotTruncateFile($location));
102
            }
103
            $file->rewind();
104
            unset($file);
105
        } catch (RuntimeException $ex) {
106
            throw new UploadException($this->lang->uppCannotTruncateFile($location), 0, $ex);
107
        }
108
    }
109
}
110