FilesManagement   C
last analyzed

Complexity

Total Complexity 54

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 79
c 2
b 1
f 0
dl 0
loc 217
rs 6.4799
wmc 54

7 Methods

Rating   Name   Duplication   Size   Complexity  
A createFolder() 0 12 6
A copyFile() 0 3 1
B rcopy() 0 28 11
B rmove() 0 31 11
B recurseCopy() 0 17 7
B rrmdir() 0 31 9
B deleteDirectory() 0 35 9

How to fix   Complexity   

Complex Class

Complex classes like FilesManagement often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FilesManagement, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Tag\Common;
4
5
/*
6
 You may not change or alter any portion of this comment or credits
7
 of supporting developers from this source code or any supporting source code
8
 which is considered copyrighted (c) material of the original comment or credit authors.
9
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * @copyright   XOOPS Project (https://xoops.org)
17
 * @license     https://www.fsf.org/copyleft/gpl.html GNU public license
18
 * @author      mamba <[email protected]>
19
 */
20
trait FilesManagement
21
{
22
    /**
23
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
24
     *
25
     * @param string $folder The full path of the directory to check
26
     *
27
     * @throws \RuntimeException
28
     */
29
    public static function createFolder(string $folder): void
30
    {
31
        try {
32
            if (!\is_dir($folder)) {
33
                if (!\is_dir($folder) && !\mkdir($folder) && !\is_dir($folder)) {
34
                    throw new \RuntimeException(\sprintf('Unable to create the %s directory', $folder));
35
                }
36
37
                file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
38
            }
39
        } catch (\Throwable $e) {
40
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
41
        }
42
    }
43
44
    public static function copyFile(string $file, string $folder): bool
45
    {
46
        return \copy($file, $folder);
47
    }
48
49
    public static function recurseCopy(string $src, string $dst): void
50
    {
51
        $dir = \opendir($src);
52
        //        @mkdir($dst);
53
        if (!@\mkdir($dst) && !\is_dir($dst)) {
54
            throw new \RuntimeException('The directory ' . $dst . ' could not be created.');
55
        }
56
        while (false !== ($file = \readdir($dir))) {
57
            if (('.' !== $file) && ('..' !== $file)) {
58
                if (\is_dir($src . '/' . $file)) {
59
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
60
                } else {
61
                    \copy($src . '/' . $file, $dst . '/' . $file);
62
                }
63
            }
64
        }
65
        \closedir($dir);
66
    }
67
68
    /**
69
     * Remove files and (sub)directories
70
     *
71
     * @param string $src source directory to delete
72
     *
73
     * @return bool true on success
74
     * @uses \Xmf\Module\Helper::isUserAdmin()
75
     *
76
     * @uses \Xmf\Module\Helper::getHelper()
77
     */
78
    public static function deleteDirectory(string $src): bool
79
    {
80
        // Only continue if user is a 'global' Admin
81
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
82
            return false;
83
        }
84
85
        $success = true;
86
        // remove old files
87
        $dirInfo = new \SplFileInfo($src);
88
        // validate is a directory
89
        if ($dirInfo->isDir()) {
90
            $fileList = \array_diff(\scandir($src, \SCANDIR_SORT_NONE), ['..', '.']);
91
            foreach ($fileList as $k => $v) {
92
                $fileInfo = new \SplFileInfo("{$src}/{$v}");
93
                if ($fileInfo->isDir()) {
94
                    // recursively handle subdirectories
95
                    if (!$success = self::deleteDirectory($fileInfo->getRealPath())) {
96
                        break;
97
                    }
98
                    // delete the file
99
                } elseif (!($success = \unlink($fileInfo->getRealPath()))) {
100
                    break;
101
                }
102
            }
103
            // now delete this (sub)directory if all the files are gone
104
            if ($success) {
105
                $success = \rmdir($dirInfo->getRealPath());
106
            }
107
        } else {
108
            // input is not a valid directory
109
            $success = false;
110
        }
111
112
        return $success;
113
    }
114
115
    /**
116
     * Recursively remove directory
117
     *
118
     * @todo currently won't remove directories with hidden files, should it?
119
     *
120
     * @param string $src directory to remove (delete)
121
     *
122
     * @return bool true on success
123
     */
124
    public static function rrmdir(string $src): bool
125
    {
126
        // Only continue if user is a 'global' Admin
127
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
128
            return false;
129
        }
130
131
        // If source is not a directory stop processing
132
        if (!\is_dir($src)) {
133
            return false;
134
        }
135
136
        //        $success = true;
137
138
        // Open the source directory to read in files
139
        $iterator = new \DirectoryIterator($src);
140
        foreach ($iterator as $fObj) {
141
            if ($fObj->isFile()) {
142
                $filename = $fObj->getPathname();
143
                $fObj     = null; // clear this iterator object to close the file
0 ignored issues
show
Unused Code introduced by
The assignment to $fObj is dead and can be removed.
Loading history...
144
                if (!\unlink($filename)) {
145
                    return false; // couldn't delete the file
146
                }
147
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
148
                // Try recursively on directory
149
                self::rrmdir($fObj->getPathname());
150
            }
151
        }
152
        $iterator = null;   // clear iterator Obj to close file/directory
0 ignored issues
show
Unused Code introduced by
The assignment to $iterator is dead and can be removed.
Loading history...
153
154
        return \rmdir($src); // remove the directory & return results
155
    }
156
157
    /**
158
     * Recursively move files from one directory to another
159
     *
160
     * @param string $src  - Source of files being moved
161
     * @param string $dest - Destination of files being moved
162
     *
163
     * @return bool true on success
164
     */
165
    public static function rmove(string $src, string $dest): bool
166
    {
167
        // Only continue if user is a 'global' Admin
168
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
169
            return false;
170
        }
171
172
        // If source is not a directory stop processing
173
        if (!\is_dir($src)) {
174
            return false;
175
        }
176
177
        // If the destination directory does not exist and could not be created stop processing
178
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
179
            return false;
180
        }
181
182
        // Open the source directory to read in files
183
        $iterator = new \DirectoryIterator($src);
184
        foreach ($iterator as $fObj) {
185
            if ($fObj->isFile()) {
186
                \rename($fObj->getPathname(), "$dest/" . $fObj->getFilename());
187
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
188
                // Try recursively on directory
189
                self::rmove($fObj->getPathname(), "$dest/" . $fObj->getFilename());
190
                //                rmdir($fObj->getPath()); // now delete the directory
191
            }
192
        }
193
        $iterator = null;   // clear iterator Obj to close file/directory
0 ignored issues
show
Unused Code introduced by
The assignment to $iterator is dead and can be removed.
Loading history...
194
195
        return \rmdir($src); // remove the directory & return results
196
    }
197
198
    /**
199
     * Recursively copy directories and files from one directory to another
200
     *
201
     * @param string $src  - Source of files being moved
202
     * @param string $dest - Destination of files being moved
203
     *
204
     * @return bool true on success
205
     * @uses \Xmf\Module\Helper::isUserAdmin()
206
     *
207
     * @uses \Xmf\Module\Helper::getHelper()
208
     */
209
    public static function rcopy(string $src, string $dest): bool
210
    {
211
        // Only continue if user is a 'global' Admin
212
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
213
            return false;
214
        }
215
216
        // If source is not a directory stop processing
217
        if (!\is_dir($src)) {
218
            return false;
219
        }
220
221
        // If the destination directory does not exist and could not be created stop processing
222
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
223
            return false;
224
        }
225
226
        // Open the source directory to read in files
227
        $iterator = new \DirectoryIterator($src);
228
        foreach ($iterator as $fObj) {
229
            if ($fObj->isFile()) {
230
                \copy($fObj->getPathname(), "$dest/" . $fObj->getFilename());
231
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
232
                self::rcopy($fObj->getPathname(), "$dest/" . $fObj->getFilename());
233
            }
234
        }
235
236
        return true;
237
    }
238
}
239