FilesManagement::xcopy()   B
last analyzed

Complexity

Conditions 10
Paths 7

Size

Total Lines 45
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 15
nc 7
nop 2
dl 0
loc 45
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace XoopsModules\Chess\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
     * @throws \RuntimeException
28
     */
29
    public static function createFolder($folder)
30
    {
31
        try {
32
            if (!\file_exists($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(), '<br>';
41
        }
42
    }
43
44
    /**
45
     * @param $file
46
     * @param $folder
47
     * @return bool
48
     */
49
    public static function copyFile($file, $folder)
50
    {
51
        return \copy($file, $folder);
52
    }
53
54
    /**
55
     * @param $src
56
     * @param $dst
57
     */
58
    public static function recurseCopy($src, $dst)
59
    {
60
        $dir = \opendir($src);
61
        //        @mkdir($dst);
62
63
        if (!@\mkdir($dst) && !\is_dir($dst)) {
64
            throw new \RuntimeException('The directory ' . $dst . ' could not be created.');
65
        }
66
67
        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

67
        while (false !== ($file = \readdir(/** @scrutinizer ignore-type */ $dir))) {
Loading history...
68
            if (('.' !== $file) && ('..' !== $file)) {
69
                if (\is_dir($src . '/' . $file)) {
70
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
71
                } else {
72
                    \copy($src . '/' . $file, $dst . '/' . $file);
73
                }
74
            }
75
        }
76
77
        \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

77
        \closedir(/** @scrutinizer ignore-type */ $dir);
Loading history...
78
    }
79
80
    /**
81
     * Copy a file, or recursively copy a folder and its contents
82
     * @param string $source Source path
83
     * @param string $dest   Destination path
84
     * @return      bool     Returns true on success, false on failure
85
     * @author      Aidan Lister <[email protected]>
86
     * @version     1.0.1
87
     * @link        http://aidanlister.com/2004/04/recursively-copying-directories-in-php/
88
     */
89
    public static function xcopy($source, $dest)
90
    {
91
        // Check for symlinks
92
93
        if (\is_link($source)) {
94
            return \symlink(\readlink($source), $dest);
95
        }
96
97
        // Simple copy for a file
98
99
        if (\is_file($source)) {
100
            return \copy($source, $dest);
101
        }
102
103
        // Make destination directory
104
105
        if (!\is_dir($dest)) {
106
            if (!\mkdir($dest) && !\is_dir($dest)) {
107
                throw new \RuntimeException(\sprintf('Directory "%s" was not created', $dest));
108
            }
109
        }
110
111
        // Loop through the folder
112
113
        $dir = \dir($source);
114
115
        if (@\is_dir($dir)) {
116
            while (false !== $entry = $dir->read()) {
117
                // Skip pointers
118
119
                if ('.' === $entry || '..' === $entry) {
120
                    continue;
121
                }
122
123
                // Deep copy directories
124
125
                self::xcopy("$source/$entry", "$dest/$entry");
126
            }
127
128
            // Clean up
129
130
            $dir->close();
131
        }
132
133
        return true;
134
    }
135
136
    /**
137
     * Remove files and (sub)directories
138
     *
139
     * @param string $src source directory to delete
140
     *
141
     * @return bool true on success
142
     * @uses \Xmf\Module\Helper::isUserAdmin()
143
     *
144
     * @uses \Xmf\Module\Helper::getHelper()
145
     */
146
    public static function deleteDirectory($src)
147
    {
148
        // Only continue if user is a 'global' Admin
149
150
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
151
            return false;
152
        }
153
154
        $success = true;
155
156
        // remove old files
157
158
        $dirInfo = new \SplFileInfo($src);
159
160
        // validate is a directory
161
162
        if ($dirInfo->isDir()) {
163
            $fileList = \array_diff(\scandir($src, \SCANDIR_SORT_NONE), ['..', '.']);
0 ignored issues
show
Bug introduced by
It seems like scandir($src, SCANDIR_SORT_NONE) can also be of type false; however, parameter $array1 of array_diff() does only seem to accept array, 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

163
            $fileList = \array_diff(/** @scrutinizer ignore-type */ \scandir($src, \SCANDIR_SORT_NONE), ['..', '.']);
Loading history...
164
165
            foreach ($fileList as $k => $v) {
166
                $fileInfo = new \SplFileInfo("{$src}/{$v}");
167
168
                if ($fileInfo->isDir()) {
169
                    // recursively handle subdirectories
170
171
                    if (!$success = self::deleteDirectory($fileInfo->getRealPath())) {
172
                        break;
173
                    }
174
                } elseif (!($success = \unlink($fileInfo->getRealPath()))) {
175
                    break;
176
                }
177
            }
178
179
            // now delete this (sub)directory if all the files are gone
180
181
            if ($success) {
182
                $success = \rmdir($dirInfo->getRealPath());
183
            }
184
        } else {
185
            // input is not a valid directory
186
187
            $success = false;
188
        }
189
190
        return $success;
191
    }
192
193
    /**
194
     * Recursively remove directory
195
     *
196
     * @todo currently won't remove directories with hidden files, should it?
197
     *
198
     * @param string $src directory to remove (delete)
199
     *
200
     * @return bool true on success
201
     */
202
    public static function rrmdir($src)
203
    {
204
        // Only continue if user is a 'global' Admin
205
206
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
207
            return false;
208
        }
209
210
        // If source is not a directory stop processing
211
212
        if (!\is_dir($src)) {
213
            return false;
214
        }
215
216
        $success = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
217
218
        // Open the source directory to read in files
219
220
        $iterator = new \DirectoryIterator($src);
221
222
        foreach ($iterator as $fObj) {
223
            if ($fObj->isFile()) {
224
                $filename = $fObj->getPathname();
225
226
                $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...
227
228
                if (!\unlink($filename)) {
229
                    return false; // couldn't delete the file
230
                }
231
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
232
                // Try recursively on directory
233
234
                self::rrmdir($fObj->getPathname());
235
            }
236
        }
237
238
        $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...
239
        return \rmdir($src); // remove the directory & return results
240
    }
241
242
    /**
243
     * Recursively move files from one directory to another
244
     *
245
     * @param string $src  - Source of files being moved
246
     * @param string $dest - Destination of files being moved
247
     *
248
     * @return bool true on success
249
     */
250
    public static function rmove($src, $dest)
251
    {
252
        // Only continue if user is a 'global' Admin
253
254
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
255
            return false;
256
        }
257
258
        // If source is not a directory stop processing
259
260
        if (!\is_dir($src)) {
261
            return false;
262
        }
263
264
        // If the destination directory does not exist and could not be created stop processing
265
266
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
267
            return false;
268
        }
269
270
        // Open the source directory to read in files
271
272
        $iterator = new \DirectoryIterator($src);
273
274
        foreach ($iterator as $fObj) {
275
            if ($fObj->isFile()) {
276
                \rename($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
277
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
278
                // Try recursively on directory
279
280
                self::rmove($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
281
                //                rmdir($fObj->getPath()); // now delete the directory
282
            }
283
        }
284
285
        $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...
286
        return \rmdir($src); // remove the directory & return results
287
    }
288
289
    /**
290
     * Recursively copy directories and files from one directory to another
291
     *
292
     * @param string $src  - Source of files being moved
293
     * @param string $dest - Destination of files being moved
294
     *
295
     * @return bool true on success
296
     * @uses \Xmf\Module\Helper::isUserAdmin()
297
     *
298
     * @uses \Xmf\Module\Helper::getHelper()
299
     */
300
    public static function rcopy($src, $dest)
301
    {
302
        // Only continue if user is a 'global' Admin
303
304
        if (!($GLOBALS['xoopsUser'] instanceof \XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
305
            return false;
306
        }
307
308
        // If source is not a directory stop processing
309
310
        if (!\is_dir($src)) {
311
            return false;
312
        }
313
314
        // If the destination directory does not exist and could not be created stop processing
315
316
        if (!\is_dir($dest) && !\mkdir($dest) && !\is_dir($dest)) {
317
            return false;
318
        }
319
320
        // Open the source directory to read in files
321
322
        $iterator = new \DirectoryIterator($src);
323
324
        foreach ($iterator as $fObj) {
325
            if ($fObj->isFile()) {
326
                \copy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
327
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
328
                self::rcopy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
329
            }
330
        }
331
332
        return true;
333
    }
334
}
335