Completed
Push — develop ( 5d5326...be0e9e )
by Christian
02:27
created

src/N98/Util/Filesystem.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * this file is part of magerun
4
 *
5
 * @author Tom Klingenberg <https://github.com/ktomk>
6
 */
7
8
namespace N98\Util;
9
10
use RuntimeException;
11
12
/**
13
 * Class Filesystem
14
 *
15
 * @package N98\Util
16
 */
17
class Filesystem
18
{
19
    /**
20
     * @param string $src
21
     * @param string $dst
22
     * @param string[]  $blacklist
23
     *
24
     * @return void
25
     */
26
    public function recursiveCopy($src, $dst, $blacklist = [])
27
    {
28
        if (!is_dir($dst)) {
29
            @mkdir($dst, 0777, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
30
        }
31
32
        if (!is_dir($dst)) {
33
            throw new RuntimeException(sprintf('Destination directory <%s> error', $dst));
34
        }
35
36
        $handle = opendir($src);
37
38
        if (!$handle) {
39
            throw new RuntimeException(sprintf('Source directory <%s> error', $src));
40
        }
41
42
        $skip = array_merge(['.', '..'], $blacklist);
43
        $stack = [];
44
45
        while (false !== ($file = readdir($handle))) {
46
            if (in_array($file, $skip)) {
47
                continue;
48
            }
49
50
            if (is_dir($src . '/' . $file)) {
51
                $stack[] = $file;
52
            } else {
53
                copy($src . '/' . $file, $dst . '/' . $file);
54
            }
55
        }
56
        closedir($handle);
57
58
        foreach ($stack as $file) {
59
            $this->recursiveCopy($src . '/' . $file, $dst . '/' . $file, $blacklist);
60
        }
61
    }
62
63
    /**
64
     * @param string $directory
65
     * @param bool $empty
66
     *
67
     * @see http://lixlpixel.org/recursive_function/php/recursive_directory_delete/
68
     *
69
     * @return bool
70
     */
71
    public function recursiveRemoveDirectory($directory, $empty = false)
72
    {
73
        // if the path has a slash at the end we remove it here
74
        if (substr($directory, -1) === '/') {
75
            $directory = substr($directory, 0, -1);
76
        }
77
78
        // if the path is not valid or is not a directory ...
79
        // ... if the path is not readable
80
        if (!is_dir($directory) || !is_readable($directory)) {
81
            return false;
82
        }
83
84
        // we open the directory
85
        $handle = opendir($directory);
86
87
        if (!$handle) {
88
            throw new RuntimeException(sprintf('Directory <%s> error', $directory));
89
        }
90
91
        $skip = ['.', '..'];
92
93
        // and scan through the items inside
94
        while (false !== ($file = readdir($handle))) {
95
            // if the filepointer is not the current directory
96
            // or the parent directory
97
            if (in_array($file, $skip)) {
98
                continue;
99
            }
100
101
            // we build the new path to delete
102
            $path = $directory . '/' . $file;
103
104
            // if the new path is a directory
105
            // don't recursively delete symlinks - just remove the actual link
106
            // this is helpful for extensions sym-linked from vendor directory
107
            // previous behaviour would wipe out the files in the vendor directory
108
            if (!is_link($path) && is_dir($path)) {
109
                // we call this function with the new path
110
                $this->recursiveRemoveDirectory($path);
111
112
            // if the new path is a file
113
            } else {
114
                // we remove the file
115
                unlink($path);
116
            }
117
        }
118
        closedir($handle);
119
120
        // if the option not empty
121
        if (!$empty) {
122
            return rmdir($directory);
123
        }
124
125
        // return success
126
        return true;
127
    }
128
129
    /**
130
     * @param int $bytes
131
     * @param int $decimals
132
     *
133
     * @see http://www.php.net/manual/en/function.filesize.php#106569
134
     *
135
     * @return string
136
     */
137
    public static function humanFileSize($bytes, $decimals = 2)
138
    {
139
        $units = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
140
        $factor = (int) floor((strlen($bytes) - 1) / 3);
141
142
        return sprintf("%.{$decimals}f%s", $bytes / pow(1024, $factor), $units[$factor]);
143
    }
144
}
145