File   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 37
dl 0
loc 106
rs 10
c 2
b 0
f 0
wmc 19

4 Methods

Rating   Name   Duplication   Size   Complexity  
A deleteDirectoryContents() 0 21 6
A delete() 0 15 5
A deletePathIfEmpty() 0 26 6
A throwIfFalse() 0 4 2
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
                self::throwIfFalse(rmdir($fullPath), "cannot delete '{$fullPath}'", 1);
41
                continue;
42
            }
43
44
            self::throwIfFalse(unlink($fullPath), "cannot delete '{$fullPath}'", 2);
45
        }
46
    }
47
48
    /**
49
     * Deletes the given file specified by $path
50
     *
51
     * @param string $path path to the file to be deleted
52
     *
53
     * @return void
54
     *
55
     * @throws \InvalidArgumentException if $path is whitespace
56
     * @throws \Exception if unlink returns false
57
     */
58
    public static function delete(string $path)
59
    {
60
        if (trim($path) === '') {
61
            throw new \InvalidArgumentException('$path is not a string or is whitespace');
62
        }
63
64
        if (!file_exists($path)) {
65
            return;
66
        }
67
68
        try {
69
            self::throwIfFalse(unlink($path), "unlink returned false for '{$path}'");
70
        } catch (\Exception $e) {
71
            if (file_exists($path)) {
72
                throw $e;
73
            }
74
        }
75
    }
76
77
    /**
78
     * Recursively deletes the given directory path until a non-empty directory is found or the $stopAtPath is reached.
79
     *
80
     * @param string $deletePath The empty directory path to delete.
81
     * @param string $stopAtPath The point at which the deletion should stop. Defaults to /.
82
     *
83
     * @return void
84
     */
85
    public static function deletePathIfEmpty(string $deletePath, string $stopAtPath = '/')
86
    {
87
        if (!file_exists($deletePath)) {
88
            return;
89
        }
90
91
        if (realpath($deletePath) === realpath($stopAtPath)) {
92
            return;
93
        }
94
95
        $handle = dir($deletePath);
96
        for ($entry = $handle->read(); $entry !== false; $entry = $handle->read()) {
97
            if ($entry == '.' || $entry == '..') {
98
                continue;
99
            }
100
101
            //dir not empty
102
            $handle->close();
103
            return;
104
        }
105
106
        rmdir($deletePath);
107
        $handle->close();
108
109
        //RECURSION!!!
110
        self::deletePathIfEmpty(dirname($deletePath), $stopAtPath);
111
    }
112
113
    private static function throwIfFalse($condition, string $message, int $code = 0)
114
    {
115
        if ($condition === false) {
116
            throw new \Exception($message, $code);
117
        }
118
    }
119
}
120