Completed
Push — master ( f1cb99...3ef691 )
by WEBEWEB
02:22
created

FileHelper::getFilenames()   B

Complexity

Conditions 7
Paths 3

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 8.4746
c 0
b 0
f 0
cc 7
nc 3
nop 2
1
<?php
2
3
/**
4
 * This file is part of the core-library package.
5
 *
6
 * (c) 2018 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WBW\Library\Core\FileSystem;
13
14
use RecursiveDirectoryIterator;
15
use RecursiveIteratorIterator;
16
use WBW\Library\Core\Exception\Argument\IllegalArgumentException;
17
use WBW\Library\Core\Exception\FileSystem\FileNotFoundException;
18
use WBW\Library\Core\Exception\FileSystem\IOException;
19
use ZipArchive;
20
21
/**
22
 * File helper.
23
 *
24
 * @author webeweb <https://github.com/webeweb/>
25
 * @package WBW\Library\Core\IO
26
 */
27
class FileHelper implements FileInterface {
28
29
    /**
30
     * Append to.
31
     *
32
     * @param string $src The source filename.
33
     * @param string $dest The destination filename.
34
     * @throws IOException Throws an I/O exception if an error occurs.
35
     */
36
    public static function appendTo($src, $dest) {
37
38
        // Open the destination.
39
        $reader = @fopen($src, "r");
40
        if (false === $reader) {
41
            throw new FileNotFoundException($src);
42
        }
43
44
        // Open the destination.
45
        $writer = @fopen($dest, "w");
46
        if (false === $writer) {
47
            throw new IOException(sprintf("Failed to open \"%s\"", $dest));
48
        }
49
50
        // Append the source into destination.
51
        if (false === @file_put_contents($dest, $reader, FILE_APPEND)) {
52
            throw new IOException(sprintf("Failed to append \"%s\" into \"%s\"", $src, $dest));
53
        }
54
    }
55
56
    /**
57
     * Delete a file.
58
     *
59
     * @param string $filename The filename.
60
     * @return boolean Returns true in case of success, false otherwise.
61
     * @throws FileNotFoundException Throws a file not found exception if the file does not exists.
62
     */
63
    public static function delete($filename) {
64
        if (false === file_exists($filename)) {
65
            throw new FileNotFoundException($filename);
66
        }
67
        return unlink($filename);
68
    }
69
70
    /**
71
     * Format a size.
72
     *
73
     * @param  $size The size.
74
     * @param string $unit The unit.
75
     * @return string Returns the formated size.
76
     */
77
    public static function formatSize($size, $unit = null, $decimals = 2) {
78
79
80
        // Initialize the units.
81
        $units = self::getUnits();
82
83
        // Find the unit.
84
        $index = array_search($unit, $units);
85
        if (null !== $unit && false === $index) {
86
            throw new IllegalArgumentException("The unit \"" . $unit . "\" does not exists");
87
        }
88
89
        // Initialize the output.
90
        $output = $size;
91
92
        $iteration = 0;
93
        while (self::FILE_SIZE_DIVIDER <= $output || $iteration < $index) {
94
            $output /= self::FILE_SIZE_DIVIDER;
95
            ++$iteration;
96
        }
97
98
        // Return the output.
99
        return implode(" ", [sprintf("%." . $decimals . "f", $output), $units[$iteration]]);
100
    }
101
102
    /**
103
     * Get a file contents.
104
     *
105
     * @param string $filename The filename.
106
     * @return string Returns the file contents.
107
     * @throws FileNotFoundException Throws a file not found exception if the file does not exists.
108
     */
109
    public static function getContents($filename) {
110
        if (false === file_exists($filename)) {
111
            throw new FileNotFoundException($filename);
112
        }
113
        return file_get_contents($filename);
114
    }
115
116
    /**
117
     * Get the filenames.
118
     *
119
     * @param string $pathname The pathname.
120
     * @param string $extension The file extension.
121
     * @return array Returns the filenames.
122
     * @throws FileNotFoundException Throws a file not found exception if the directory does not exists.
123
     */
124
    public static function getFilenames($pathname, $extension = null) {
125
126
        // Check if the directory exists.
127
        if (false === file_exists($pathname)) {
128
            throw new FileNotFoundException($pathname);
129
        }
130
131
        // Initialize the filenames.
132
        $filenames = [];
133
134
        // Open the directory.
135
        if (false !== ($directory = opendir($pathname))) {
136
137
            // Initialize the offset.
138
            $offset = strlen($extension);
139
140
            // Read the directory.
141
            while (($file = readdir($directory)) !== false) {
142
143
                // Determines if the file should be added.
144
                if (false === in_array($file, [".", ".."]) && ((null === $extension) || 0 === substr_compare($file, $extension, -$offset))) {
145
                    $filenames[] = $file;
146
                }
147
            }
148
149
            // Close the directory.
150
            closedir($directory);
151
        }
152
153
        // Return the filenames.
154
        return $filenames;
155
    }
156
157
    /**
158
     * Get a file size.
159
     *
160
     * @param string $filename The filename.
161
     * @return int Returns the file size.
162
     * @throws FileNotFoundException Throws a File not found exception if the file does not exists.
163
     */
164
    public static function getSize($filename) {
165
        if (false === file_exists($filename)) {
166
            throw new FileNotFoundException($filename);
167
        }
168
        clearstatcache();
169
        return filesize($filename);
170
    }
171
172
    /**
173
     * Get the units.
174
     *
175
     * @return array Returns the units.
176
     */
177
    public static function getUnits() {
178
        return [
179
            self::FILE_SIZE_UNIT_B,
180
            self::FILE_SIZE_UNIT_KB,
181
            self::FILE_SIZE_UNIT_MB,
182
            self::FILE_SIZE_UNIT_GB,
183
            self::FILE_SIZE_UNIT_TB,
184
            self::FILE_SIZE_UNIT_PB,
185
            self::FILE_SIZE_UNIT_EB,
186
            self::FILE_SIZE_UNIT_ZB,
187
            self::FILE_SIZE_UNIT_YB,
188
        ];
189
    }
190
191
    /**
192
     * Rename a file.
193
     *
194
     * @param string $oldFilename The old filename.
195
     * @param string $newFilename The new filename.
196
     * @return boolean Returns true in case of success, false otherwise or null if the new filename already exists.
197
     * @throws FileNotFoundException Throws a file not found exception if the file does not exists.
198
     */
199
    public static function rename($oldFilename, $newFilename) {
200
        if (false === file_exists($oldFilename)) {
201
            throw new FileNotFoundException($oldFilename);
202
        }
203
        if (true === file_exists($newFilename)) {
204
            return null;
205
        }
206
        return rename($oldFilename, $newFilename);
207
    }
208
209
    /**
210
     * Zip a file.
211
     *
212
     * @param string $source The source filename.
213
     * @param string $destination The destination filename.
214
     * @return boolean Returns true in case of success, false otherwise.
215
     * @throws FileNotFoundException Throws a file not found exception if the source filename is not found.
216
     */
217
    public static function zip($source, $destination) {
218
219
        // Check if the filename exists.
220
        if (false === file_exists($source)) {
221
            throw new FileNotFoundException($source);
222
        }
223
224
        // Initialize the ZIP archive.
225
        $zip = new ZipArchive();
226
        $zip->open($destination, ZipArchive::CREATE);
227
228
        // Clean up.
229
        $src = str_replace("\\\\", "/", realpath($source));
230
231
        // Is file ? => Add it and return.
232
        if (true === is_file($src)) {
233
            $zip->addFromString(basename($src), self::getContents($src));
234
            return $zip->close();
235
        }
236
237
        // Handle the files list.
238
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src), RecursiveIteratorIterator::SELF_FIRST);
239
        foreach ($files as $current) {
240
241
            // Clean up.
242
            $cur = str_replace("\\\\", "/", realpath($current));
243
244
            // Initialize the ZIP path.
245
            $zipPath = preg_replace("/^" . str_replace("/", "\/", $src . "/") . "/", "", $cur);
246
247
            // Check the file type.
248
            if (true === is_file($cur)) {
249
                $zip->addFromString($zipPath, self::getContents($cur));
250
            }
251
            if (true === is_dir($cur)) {
252
                $zip->addEmptyDir($zipPath);
253
            }
254
        }
255
    }
256
257
}
258