Completed
Push — master ( 7942ad...1c8947 )
by WEBEWEB
01:50
created

FileUtility::getFilenames()   C

Complexity

Conditions 7
Paths 3

Size

Total Lines 32
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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