FilesManagement   F
last analyzed

Complexity

Total Complexity 61

Size/Duplication

Total Lines 271
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 96
dl 0
loc 271
rs 3.52
c 0
b 0
f 0
wmc 61

8 Methods

Rating   Name   Duplication   Size   Complexity  
B rcopy() 0 27 11
B xcopy() 0 34 10
A createFolder() 0 12 5
B deleteDirectory() 0 39 9
B rrmdir() 0 30 9
A copyFile() 0 3 1
A recurseCopy() 0 13 5
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 namespace XoopsModules\Cardealer\Common;
2
3
/*
4
 You may not change or alter any portion of this comment or credits
5
 of supporting developers from this source code or any supporting source code
6
 which is considered copyrighted (c) material of the original comment or credit authors.
7
8
 This program is distributed in the hope that it will be useful,
9
 but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
*/
12
13
/**
14
 * Module: cardealer
15
 *
16
 * @category        Module
17
 * @package         cardealer
18
 * @author          XOOPS Development Team <[email protected]> - <https://xoops.org>
19
 * @copyright       {@link https://xoops.org/ XOOPS Project}
20
 * @license         GPL 2.0 or later
21
 * @link            https://xoops.org/
22
 * @since           1.0.0
23
 */
24
trait FilesManagement
25
{
26
    /**
27
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
28
     *
29
     * @param string $folder The full path of the directory to check
30
     *
31
     * @return void
32
     * @throws \RuntimeException
33
     */
34
    public static function createFolder($folder)
35
    {
36
        try {
37
            if (!file_exists($folder)) {
38
                if (!mkdir($folder) && !is_dir($folder)) {
39
                    throw new \RuntimeException(sprintf('Unable to create the %s directory', $folder));
40
                }
41
42
                file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
43
            }
44
        } catch (\Exception $e) {
45
            echo 'Caught exception: ', $e->getMessage(), '<br>';
46
        }
47
    }
48
49
    /**
50
     * @param $file
51
     * @param $folder
52
     * @return bool
53
     */
54
    public static function copyFile($file, $folder)
55
    {
56
        return copy($file, $folder);
57
    }
58
59
    /**
60
     * @param $src
61
     * @param $dst
62
     */
63
    public static function recurseCopy($src, $dst)
64
    {
65
        $dir = opendir($src);
66
        while (false !== ($file = readdir($dir))) {
0 ignored issues
show
Bug introduced by
It seems like $dir can also be of type false; however, parameter $dir_handle of readdir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

66
        while (false !== ($file = readdir(/** @scrutinizer ignore-type */ $dir))) {
Loading history...
67
            if (('.' !== $file) && ('..' !== $file)) {
68
                if (is_dir($src . '/' . $file)) {
69
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
70
                } else {
71
                    copy($src . '/' . $file, $dst . '/' . $file);
72
                }
73
            }
74
        }
75
        closedir($dir);
0 ignored issues
show
Bug introduced by
It seems like $dir can also be of type false; however, parameter $dir_handle of closedir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

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