FilesManagement   F
last analyzed

Complexity

Total Complexity 64

Size/Duplication

Total Lines 265
Duplicated Lines 0 %

Importance

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

8 Methods

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

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\Lexikon\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     http://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
    public static function createFolder($folder)
28
    {
29
        try {
30
            if (!\is_dir($folder)) {
31
                if (!\is_dir($folder) && !\mkdir($folder) && !\is_dir($folder)) {
32
                    throw new \RuntimeException(\sprintf('Unable to create the %s directory', $folder));
33
                }
34
35
                file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
36
            }
37
        } catch (\Exception $e) {
38
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
39
        }
40
    }
41
42
    /**
43
     * @param $file
44
     * @param $folder
45
     * @return bool
46
     */
47
    public static function copyFile($file, $folder)
48
    {
49
        return \copy($file, $folder);
50
    }
51
52
    /**
53
     * @param $src
54
     * @param $dst
55
     */
56
    public static function recurseCopy($src, $dst)
57
    {
58
        $dir = \opendir($src);
59
        //        @mkdir($dst);
60
        if (!@\mkdir($dst) && !\is_dir($dst)) {
61
            throw new \RuntimeException('The directory ' . $dst . ' could not be created.');
62
        }
63
        while (false !== ($file = \readdir($dir))) {
64
            if (('.' !== $file) && ('..' !== $file)) {
65
                if (\is_dir($src . '/' . $file)) {
66
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
67
                } else {
68
                    \copy($src . '/' . $file, $dst . '/' . $file);
69
                }
70
            }
71
        }
72
        \closedir($dir);
73
    }
74
75
    /**
76
     * Copy a file, or recursively copy a folder and its contents
77
     * @param string $source Source path
78
     * @param string $dest   Destination path
79
     * @return      bool     Returns true on success, false on failure
80
     * @author      Aidan Lister <[email protected]>
81
     * @version     1.0.1
82
     * @link        http://aidanlister.com/2004/04/recursively-copying-directories-in-php/
83
     */
84
    public static function xcopy($source, $dest)
85
    {
86
        // Check for symlinks
87
        if (\is_link($source)) {
88
            return \symlink(\readlink($source), $dest);
89
        }
90
91
        // Simple copy for a file
92
        if (\is_file($source)) {
93
            return \copy($source, $dest);
94
        }
95
96
        // Make destination directory
97
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
98
            throw new \RuntimeException(\sprintf('Directory "%s" was not created', $dest));
99
        }
100
101
        // Loop through the folder
102
        $dir = \dir($source);
103
        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

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