Completed
Pull Request — master (#3)
by Chad
08:15
created

File::delete()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 11
nc 7
nop 1
1
<?php
2
/**
3
 * Defines the \TraderInteractive\Util\File class.
4
 */
5
6
namespace TraderInteractive\Util;
7
8
/**
9
 * Class of static file utility functions.
10
 */
11
final class File
12
{
13
    /**
14
     * Recursively deletes directory contents
15
     *
16
     * @param string $directoryPath absolute path of directory
17
     *
18
     * @return void
19
     *
20
     * @throws \Exception if file cannot be deleted
21
     * @throws \Exception if directory cannot be deleted
22
     * @throws \Exception if $directoryPath cannot be listed
23
     */
24
    public static function deleteDirectoryContents(string $directoryPath)
25
    {
26
        $paths = scandir($directoryPath);
27
        if ($paths === false) {
28
            throw new \Exception("cannot list directory '{$directoryPath}'");
29
        }
30
31
        foreach ($paths as $path) {
32
            if ($path === '.' || $path === '..') {
33
                continue;
34
            }
35
36
            $fullPath = "{$directoryPath}/{$path}";
37
38
            if (is_dir($fullPath)) {
39
                self::deleteDirectoryContents($fullPath);//RECURSIVE CALL
40
                if (!rmdir($fullPath)) {
41
                    throw new \Exception("cannot delete '{$fullPath}'", 1);
42
                }
43
            } else {
44
                if (!unlink($fullPath)) {
45
                    throw new \Exception("cannot delete '{$fullPath}'", 2);
46
                }
47
            }
48
        }
49
    }
50
51
    /**
52
     * Deletes the given file specified by $path
53
     *
54
     * @param string $path path to the file to be deleted
55
     *
56
     * @return void
57
     *
58
     * @throws \InvalidArgumentException if $path is whitespace
59
     * @throws \Exception if unlink returns false
60
     */
61
    public static function delete(string $path)
62
    {
63
        if (trim($path) === '') {
64
            throw new \InvalidArgumentException('$path is not a string or is whitespace');
65
        }
66
67
        if (!file_exists($path)) {
68
            return;
69
        }
70
71
        try {
72
            if (unlink($path) === false) {
73
                throw new \Exception("unlink returned false for '{$path}'");
74
            }
75
        } catch (\Exception $e) {
76
            if (file_exists($path)) {
77
                throw $e;
78
            }
79
        }
80
    }
81
82
    /**
83
     * Recursively deletes the given directory path until a non-empty directory is found or the $stopAtPath is reached.
84
     *
85
     * @param string $deletePath The empty directory path to delete.
86
     * @param string $stopAtPath The point at which the deletion should stop. Defaults to /.
87
     *
88
     * @return void
89
     */
90
    public static function deletePathIfEmpty(string $deletePath, string $stopAtPath = '/')
91
    {
92
        if (!file_exists($deletePath)) {
93
            return;
94
        }
95
96
        if (realpath($deletePath) === realpath($stopAtPath)) {
97
            return;
98
        }
99
100
        $handle = dir($deletePath);
101
        for ($entry = $handle->read(); $entry !== false; $entry = $handle->read()) {
102
            if ($entry == '.' || $entry == '..') {
103
                continue;
104
            }
105
106
            //dir not empty
107
            $handle->close();
108
            return;
109
        }
110
111
        rmdir($deletePath);
112
        $handle->close();
113
114
        //RECURSION!!!
115
        self::deletePathIfEmpty(dirname($deletePath), $stopAtPath);
116
    }
117
}
118