FilesManagement   F
last analyzed

Complexity

Total Complexity 64

Size/Duplication

Total Lines 269
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 64
eloc 95
c 1
b 0
f 0
dl 0
loc 269
rs 3.28

8 Methods

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

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
2
3
namespace XoopsModules\Groupmanager\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
use DirectoryIterator;
16
use Exception;
17
use RuntimeException;
18
use SplFileInfo;
19
use XoopsUser;
20
21
22
23
/**
24
 * @copyright   XOOPS Project (https://xoops.org)
25
 * @license     http://www.fsf.org/copyleft/gpl.html GNU public license
26
 * @author      mamba <[email protected]>
27
 */
28
trait FilesManagement
29
{
30
    /**
31
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
32
     *
33
     * @param string $folder The full path of the directory to check
34
     *
35
     * @throws \RuntimeException
36
     */
37
    public static function createFolder($folder)
38
    {
39
        try {
40
            if (!\is_dir($folder)) {
41
                if (!\is_dir($folder) && !\mkdir($folder) && !\is_dir($folder)) {
42
                    throw new RuntimeException(\sprintf('Unable to create the %s directory', $folder));
43
                }
44
45
                file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
46
            }
47
        } catch (Exception $e) {
48
            echo 'Caught exception: ', $e->getMessage(), '<br>';
49
        }
50
    }
51
52
    /**
53
     * @param $file
54
     * @param $folder
55
     * @return bool
56
     */
57
    public static function copyFile($file, $folder)
58
    {
59
        return \copy($file, $folder);
60
    }
61
62
    /**
63
     * @param $src
64
     * @param $dst
65
     */
66
    public static function recurseCopy($src, $dst)
67
    {
68
        $dir = \opendir($src);
69
        //        @mkdir($dst);
70
        if (!@\mkdir($dst) && !\is_dir($dst)) {
71
            throw new RuntimeException('The directory ' . $dst . ' could not be created.');
72
        }
73
        while (false !== ($file = \readdir($dir))) {
74
            if (('.' !== $file) && ('..' !== $file)) {
75
                if (\is_dir($src . '/' . $file)) {
76
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
77
                } else {
78
                    \copy($src . '/' . $file, $dst . '/' . $file);
79
                }
80
            }
81
        }
82
        \closedir($dir);
83
    }
84
85
    /**
86
     * Copy a file, or recursively copy a folder and its contents
87
     * @param string $source Source path
88
     * @param string $dest   Destination path
89
     * @return      bool     Returns true on success, false on failure
90
     * @author      Aidan Lister <[email protected]>
91
     * @version     1.0.1
92
     * @link        http://aidanlister.com/2004/04/recursively-copying-directories-in-php/
93
     */
94
    public static function xcopy($source, $dest)
95
    {
96
        // Check for symlinks
97
        if (\is_link($source)) {
98
            return \symlink(\readlink($source), $dest);
99
        }
100
101
        // Simple copy for a file
102
        if (\is_file($source)) {
103
            return \copy($source, $dest);
104
        }
105
106
        // Make destination directory
107
        if (!\is_dir($dest)) {
108
            if (!\mkdir($dest) && !\is_dir($dest)) {
109
                throw new RuntimeException(\sprintf('Directory "%s" was not created', $dest));
110
            }
111
        }
112
113
        // Loop through the folder
114
        $dir = \dir($source);
115
        if (@\is_dir($dir)) {
0 ignored issues
show
Bug introduced by
$dir of type Directory is incompatible with the type string expected by parameter $filename of is_dir(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

115
        if (@\is_dir(/** @scrutinizer ignore-type */ $dir)) {
Loading history...
116
            while (false !== $entry = $dir->read()) {
117
                // Skip pointers
118
                if ('.' === $entry || '..' === $entry) {
119
                    continue;
120
                }
121
                // Deep copy directories
122
                self::xcopy("$source/$entry", "$dest/$entry");
123
            }
124
            // Clean up
125
            $dir->close();
126
        }
127
128
        return true;
129
    }
130
131
    /**
132
     * Remove files and (sub)directories
133
     *
134
     * @param string $src source directory to delete
135
     *
136
     * @return bool true on success
137
     * @uses \Xmf\Module\Helper::isUserAdmin()
138
     *
139
     * @uses \Xmf\Module\Helper::getHelper()
140
     */
141
    public static function deleteDirectory($src)
142
    {
143
        // Only continue if user is a 'global' Admin
144
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
145
            return false;
146
        }
147
148
        $success = true;
149
        // remove old files
150
        $dirInfo = new SplFileInfo($src);
151
        // validate is a directory
152
        if ($dirInfo->isDir()) {
153
            $fileList = \array_diff(\scandir($src, \SCANDIR_SORT_NONE), ['..', '.']);
154
            foreach ($fileList as $k => $v) {
155
                $fileInfo = new SplFileInfo("{$src}/{$v}");
156
                if ($fileInfo->isDir()) {
157
                    // recursively handle subdirectories
158
                    if (!$success = self::deleteDirectory($fileInfo->getRealPath())) {
159
                        break;
160
                    }
161
                } elseif (!($success = \unlink($fileInfo->getRealPath()))) {
162
                    break;
163
                }
164
            }
165
            // now delete this (sub)directory if all the files are gone
166
            if ($success) {
167
                $success = \rmdir($dirInfo->getRealPath());
168
            }
169
        } else {
170
            // input is not a valid directory
171
            $success = false;
172
        }
173
174
        return $success;
175
    }
176
177
    /**
178
     * Recursively remove directory
179
     *
180
     * @todo currently won't remove directories with hidden files, should it?
181
     *
182
     * @param string $src directory to remove (delete)
183
     *
184
     * @return bool true on success
185
     */
186
    public static function rrmdir($src)
187
    {
188
        // Only continue if user is a 'global' Admin
189
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
190
            return false;
191
        }
192
193
        // If source is not a directory stop processing
194
        if (!\is_dir($src)) {
195
            return false;
196
        }
197
198
        $success = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
199
200
        // Open the source directory to read in files
201
        $iterator = new DirectoryIterator($src);
202
        foreach ($iterator as $fObj) {
203
            if ($fObj->isFile()) {
204
                $filename = $fObj->getPathname();
205
                $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...
206
                if (!\unlink($filename)) {
207
                    return false; // couldn't delete the file
208
                }
209
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
210
                // Try recursively on directory
211
                self::rrmdir($fObj->getPathname());
212
            }
213
        }
214
        $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...
215
        return \rmdir($src); // remove the directory & return results
216
    }
217
218
    /**
219
     * Recursively move files from one directory to another
220
     *
221
     * @param string $src  - Source of files being moved
222
     * @param string $dest - Destination of files being moved
223
     *
224
     * @return bool true on success
225
     */
226
    public static function rmove($src, $dest)
227
    {
228
        // Only continue if user is a 'global' Admin
229
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
230
            return false;
231
        }
232
233
        // If source is not a directory stop processing
234
        if (!\is_dir($src)) {
235
            return false;
236
        }
237
238
        // If the destination directory does not exist and could not be created stop processing
239
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
240
            return false;
241
        }
242
243
        // Open the source directory to read in files
244
        $iterator = new DirectoryIterator($src);
245
        foreach ($iterator as $fObj) {
246
            if ($fObj->isFile()) {
247
                \rename($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
248
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
249
                // Try recursively on directory
250
                self::rmove($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
251
                //                rmdir($fObj->getPath()); // now delete the directory
252
            }
253
        }
254
        $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...
255
        return \rmdir($src); // remove the directory & return results
256
    }
257
258
    /**
259
     * Recursively copy directories and files from one directory to another
260
     *
261
     * @param string $src  - Source of files being moved
262
     * @param string $dest - Destination of files being moved
263
     *
264
     * @return bool true on success
265
     * @uses \Xmf\Module\Helper::isUserAdmin()
266
     *
267
     * @uses \Xmf\Module\Helper::getHelper()
268
     */
269
    public static function rcopy($src, $dest)
270
    {
271
        // Only continue if user is a 'global' Admin
272
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
273
            return false;
274
        }
275
276
        // If source is not a directory stop processing
277
        if (!\is_dir($src)) {
278
            return false;
279
        }
280
281
        // If the destination directory does not exist and could not be created stop processing
282
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
283
            return false;
284
        }
285
286
        // Open the source directory to read in files
287
        $iterator = new DirectoryIterator($src);
288
        foreach ($iterator as $fObj) {
289
            if ($fObj->isFile()) {
290
                \copy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
291
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
292
                self::rcopy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
293
            }
294
        }
295
296
        return true;
297
    }
298
}
299