Passed
Push — master ( fba3db...2b14a7 )
by Petr
03:12
created

ProcessFile::saveFile()   B

Complexity

Conditions 6
Paths 14

Size

Total Lines 49
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 6.0163

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 32
c 1
b 0
f 0
nc 14
nop 3
dl 0
loc 49
ccs 24
cts 26
cp 0.9231
crap 6.0163
rs 8.7857
1
<?php
2
3
namespace kalanis\kw_files\Processing\Volume;
4
5
6
use kalanis\kw_files\FilesException;
7
use kalanis\kw_files\Interfaces\IFLTranslations;
8
use kalanis\kw_files\Interfaces\IProcessFiles;
9
use kalanis\kw_files\Processing\TPath;
10
use kalanis\kw_files\Traits\TLang;
11
use kalanis\kw_files\Traits\TStreamToPos;
12
use kalanis\kw_files\Traits\TToStream;
13
use kalanis\kw_paths\Extras\TPathTransform;
14
use kalanis\kw_paths\PathsException;
15
use Throwable;
16
17
18
/**
19
 * Class ProcessFile
20
 * @package kalanis\kw_files\Processing\Volume
21
 * Process files in many ways
22
 */
23
class ProcessFile implements IProcessFiles
24
{
25
    use TLang;
26
    use TPath;
27
    use TPathTransform;
28
    use TStreamToPos;
29
    use TToStream;
30
31 11
    public function __construct(string $path = '', ?IFLTranslations $lang = null)
32
    {
33 11
        $this->setPath($path);
34 11
        $this->setLang($lang);
35 11
    }
36
37 2
    public function readFile(array $entry, ?int $offset = null, ?int $length = null)
38
    {
39 2
        $path = $this->fullPath($entry);
40
        try {
41 2
            if (!is_null($length)) {
42 1
                $content = @file_get_contents($path, false, null, intval($offset), $length);
43 2
            } elseif (!is_null($offset)) {
44 1
                $content = @file_get_contents($path, false, null, $offset);
45
            } else {
46 2
                $content = @file_get_contents($path);
47
            }
48 2
            if (false !== $content) {
49 1
                return $content;
50
            }
51 1
            throw new FilesException($this->getLang()->flCannotLoadFile($path));
52 1
        } catch (Throwable $ex) {
53
            // @codeCoverageIgnoreStart
54 1
            throw new FilesException($ex->getMessage(), $ex->getCode(), $ex);
55
        }
56
        // @codeCoverageIgnoreEnd
57
    }
58
59 4
    public function saveFile(array $entry, $content, ?int $offset = null): bool
60
    {
61 4
        $path = $this->fullPath($entry);
62
        try {
63 4
            if (is_null($offset)) {  // rewrite all
64 3
                $this->writeStream($path, $this->toStream($path, $content));
65
            } else { // append from position
66 2
                if (file_exists($path)) {
67 1
                    $handler = @fopen($path, 'rb');
68 1
                    if (false === $handler) {
69
                        // @codeCoverageIgnoreStart
70
                        throw new FilesException($this->getLang()->flCannotOpenFile($path));
71
                    }
72
                    // @codeCoverageIgnoreEnd
73
                    // must be extra - need that original file handler
74 1
                    $result = $this->addStreamToPosition(
75 1
                        $handler, // original content
76 1
                        $this->toStream(
77 1
                            $path,
78
                            $content
79
                        ),
80
                        $offset
81
                    );
82 1
                    /** @scrutinizer ignore-unhandled */@fclose($handler);
83 1
                    $this->writeStream($path, $result);
84
                } else {
85 1
                    $handler = @fopen('php://memory', 'rb+');
86 1
                    if (false === $handler) {
87
                        // @codeCoverageIgnoreStart
88
                        throw new FilesException($this->getLang()->flCannotOpenFile($path));
89
                    }
90
                    // @codeCoverageIgnoreEnd
91 1
                    $this->writeStream(
92 1
                        $path,
93 1
                        $this->addStreamToPosition(
94 1
                            $handler, // no original content
95 1
                            $this->toStream(
96 1
                                $path,
97
                                $content
98
                            ),
99
                            $offset
100
                        )
101
                    );
102
                }
103
            }
104 4
            return true;
105 1
        } catch (Throwable $ex) {
106
            // @codeCoverageIgnoreStart
107 1
            throw new FilesException($this->getLang()->flCannotSaveFile($path), $ex->getCode(), $ex);
108
        }
109
        // @codeCoverageIgnoreEnd
110
    }
111
112
    /**
113
     * @param string $path
114
     * @param resource $content
115
     * @throws FilesException
116
     */
117 4
    protected function writeStream(string $path, $content): void
118
    {
119 4
        if (false === file_put_contents($path, $content)) {
120
            // @codeCoverageIgnoreStart
121
            throw new FilesException($this->getLang()->flCannotWriteFile($path));
122
        }
123 4
    }
124
125 1
    public function copyFile(array $source, array $dest): bool
126
    {
127 1
        $src = $this->fullPath($source);
128 1
        $dst = $this->fullPath($dest);
129
        try {
130 1
            return @copy($src, $dst);
131
            // @codeCoverageIgnoreStart
132
        } catch (Throwable $ex) {
133
            throw new FilesException($this->getLang()->flCannotCopyFile($src, $dst), $ex->getCode(), $ex);
134
        }
135
        // @codeCoverageIgnoreEnd
136
    }
137
138 1
    public function moveFile(array $source, array $dest): bool
139
    {
140 1
        $src = $this->fullPath($source);
141 1
        $dst = $this->fullPath($dest);
142
        try {
143 1
            return @rename($src, $dst);
144
            // @codeCoverageIgnoreStart
145
        } catch (Throwable $ex) {
146
            throw new FilesException($this->getLang()->flCannotMoveFile($src, $dst), $ex->getCode(), $ex);
147
        }
148
        // @codeCoverageIgnoreEnd
149
    }
150
151 1
    public function deleteFile(array $entry): bool
152
    {
153 1
        $path = $this->fullPath($entry);
154
        try {
155 1
            return @unlink($path);
156
            // @codeCoverageIgnoreStart
157
        } catch (Throwable $ex) {
158
            throw new FilesException($this->getLang()->flCannotRemoveFile($path), $ex->getCode(), $ex);
159
        }
160
        // @codeCoverageIgnoreEnd
161
    }
162
163
    /**
164
     * @param array<string> $path
165
     * @throws PathsException
166
     * @return string
167
     */
168 7
    protected function fullPath(array $path): string
169
    {
170 7
        return $this->getPath() . DIRECTORY_SEPARATOR . $this->compactName($path);
171
    }
172
173
    /**
174
     * @return string
175
     * @codeCoverageIgnore only when path fails
176
     */
177
    protected function noDirectoryDelimiterSet(): string
178
    {
179
        return $this->getLang()->flNoDirectoryDelimiterSet();
180
    }
181
}
182