FilesManagement::copyFile()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Suico\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
 * @category        Module
17
 * @copyright       {@link https://xoops.org/ XOOPS Project}
18
 * @license         GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
19
 * @author          Marcello Brandão aka  Suico, Mamba, LioMJ  <https://xoops.org>
20
 */
21
22
use DirectoryIterator;
23
use RuntimeException;
24
use SplFileInfo;
25
use Throwable;
26
use XoopsUser;
27
28
/**
29
 * Trait FilesManagement
30
 */
31
trait FilesManagement
32
{
33
    /**
34
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
35
     *
36
     * @param string $folder The full path of the directory to check
37
     *
38
     * @throws RuntimeException
39
     */
40
    public static function createFolder(
41
        $folder
42
    ): void {
43
        try {
44
            if (!\is_dir($folder)) {
45
                if (!\is_dir($folder) && !\mkdir($folder) && !\is_dir($folder)) {
46
                    throw new RuntimeException(\sprintf('Unable to create the %s directory', $folder));
47
                }
48
                \file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
49
            }
50
        } catch (Throwable $throwable) {
51
            echo 'Caught exception: ', $throwable->getMessage(), '<br>';
52
        }
53
    }
54
55
    /**
56
     * @param $file
57
     * @param $folder
58
     * @return bool
59
     */
60
    public static function copyFile(
61
        $file,
62
        $folder
63
    ) {
64
        return \copy($file, $folder);
65
    }
66
67
    /**
68
     * @param $src
69
     * @param $dst
70
     * @return bool
71
     */
72
    public static function recurseCopy($src, $dst)
73
    {
74
        $dir = \opendir($src);
75
        if (false === $dir) {
76
            return false;
77
        }
78
        //        @mkdir($dst);
79
        if (!@\mkdir($dst) && !\is_dir($dst)) {
80
            throw new RuntimeException('The directory ' . $dst . ' could not be created.');
81
        }
82
        while (false !== ($file = \readdir($dir))) {
83
            if (('.' !== $file) && ('..' !== $file)) {
84
                if (\is_dir($src . '/' . $file)) {
85
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
86
                } else {
87
                    \copy($src . '/' . $file, $dst . '/' . $file);
88
                }
89
            }
90
        }
91
        \closedir($dir);
92
    }
93
94
    /**
95
     * Copy a file, or recursively copy a folder and its contents
96
     * @param string $source Source path
97
     * @param string $dest   Destination path
98
     * @return      bool     Returns true on success, false on failure
99
     * @author      Aidan Lister <[email protected]>
100
     * @version     1.0.1
101
     * @link        https://aidanlister.com/2004/04/recursively-copying-directories-in-php/
102
     */
103
    public static function xcopy(
104
        $source,
105
        $dest
106
    ) {
107
        // Check for symlinks
108
        if (\is_link($source)) {
109
            return \symlink(\readlink($source), $dest);
110
        }
111
        // Simple copy for a file
112
        if (\is_file($source)) {
113
            return \copy($source, $dest);
114
        }
115
        // Make destination directory
116
        if (!\is_dir($dest)) {
117
            if (!\mkdir($dest) && !\is_dir($dest)) {
118
                throw new RuntimeException(\sprintf('Directory "%s" was not created', $dest));
119
            }
120
        }
121
        // Loop through the folder
122
        /** @var \Directory $dir */
123
        $dir = \dir($source);
124
        if (@\is_dir((string)$dir)) {
125
            while (false !== $entry = $dir->read()) {
126
                // Skip pointers
127
                if ('.' === $entry || '..' === $entry) {
128
                    continue;
129
                }
130
                // Deep copy directories
131
                self::xcopy("{$source}/{$entry}", "{$dest}/{$entry}");
132
            }
133
            // Clean up
134
            $dir->close();
135
        }
136
137
        return true;
138
    }
139
140
    /**
141
     * Remove files and (sub)directories
142
     *
143
     * @param string $src source directory to delete
144
     *
145
     * @return bool true on success
146
     * @uses \Xmf\Module\Helper::isUserAdmin()
147
     *
148
     * @uses \Xmf\Module\Helper::getHelper()
149
     */
150
    public static function deleteDirectory(
151
        $src
152
    ) {
153
        // Only continue if user is a 'global' Admin
154
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
155
            return false;
156
        }
157
        $success = true;
158
        // remove old files
159
        $dirInfo = new SplFileInfo($src);
160
        // validate is a directory
161
        if ($dirInfo->isDir()) {
162
            $fileList = \array_diff(\scandir($src, \SCANDIR_SORT_NONE), ['..', '.']);
163
            foreach ($fileList as $k => $v) {
164
                $fileInfo = new SplFileInfo("{$src}/{$v}");
165
                if ($fileInfo->isDir()) {
166
                    // recursively handle subdirectories
167
                    if (!$success = self::deleteDirectory(
168
                        $fileInfo->getRealPath()
169
                    )) {
170
                        break;
171
                    }
172
                } elseif (!($success = @\unlink($fileInfo->getRealPath()))) {
173
                    break;
174
                }
175
            }
176
            // now delete this (sub)directory if all the files are gone
177
            if ($success) {
178
                $success = \rmdir($dirInfo->getRealPath());
179
            }
180
        } else {
181
            // input is not a valid directory
182
            $success = false;
183
        }
184
185
        return $success;
186
    }
187
188
    /**
189
     * Recursively remove directory
190
     *
191
     * @todo currently won't remove directories with hidden files, should it?
192
     *
193
     * @param string $src directory to remove (delete)
194
     *
195
     * @return bool true on success
196
     */
197
    public static function rrmdir(
198
        $src
199
    ) {
200
        // Only continue if user is a 'global' Admin
201
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
202
            return false;
203
        }
204
        // If source is not a directory stop processing
205
        if (!\is_dir($src)) {
206
            return false;
207
        }
208
        $success = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
209
        // Open the source directory to read in files
210
        $iterator = new DirectoryIterator($src);
211
        foreach ($iterator as $fObj) {
212
            if ($fObj->isFile()) {
213
                $filename = $fObj->getPathname();
214
                $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...
215
                if (false === @\unlink($filename)) {
216
                    return false; // couldn't delete the file
217
                }
218
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
219
                // Try recursively on directory
220
                self::rrmdir($fObj->getPathname());
221
            }
222
        }
223
        $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...
224
225
        return \rmdir($src); // remove the directory & return results
226
    }
227
228
    /**
229
     * Recursively move files from one directory to another
230
     *
231
     * @param string $src  - Source of files being moved
232
     * @param string $dest - Destination of files being moved
233
     *
234
     * @return bool true on success
235
     */
236
    public static function rmove(
237
        $src,
238
        $dest
239
    ) {
240
        // Only continue if user is a 'global' Admin
241
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
242
            return false;
243
        }
244
        // If source is not a directory stop processing
245
        if (!\is_dir($src)) {
246
            return false;
247
        }
248
        // If the destination directory does not exist and could not be created stop processing
249
        if (!\is_dir(
250
                $dest
251
            )
252
            && !\mkdir(
253
                $dest
254
            )
255
            && !\is_dir(
256
                $dest
257
            )) {
258
            return false;
259
        }
260
        // Open the source directory to read in files
261
        $iterator = new DirectoryIterator($src);
262
        foreach ($iterator as $fObj) {
263
            if ($fObj->isFile()) {
264
                \rename($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
265
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
266
                // Try recursively on directory
267
                self::rmove($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
268
                //                rmdir($fObj->getPath()); // now delete the directory
269
            }
270
        }
271
        $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...
272
273
        return \rmdir($src); // remove the directory & return results
274
    }
275
276
    /**
277
     * Recursively copy directories and files from one directory to another
278
     *
279
     * @param string $src  - Source of files being moved
280
     * @param string $dest - Destination of files being moved
281
     *
282
     * @return bool true on success
283
     * @uses \Xmf\Module\Helper::isUserAdmin()
284
     *
285
     * @uses \Xmf\Module\Helper::getHelper()
286
     */
287
    public static function rcopy(
288
        $src,
289
        $dest
290
    ) {
291
        // Only continue if user is a 'global' Admin
292
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
293
            return false;
294
        }
295
        // If source is not a directory stop processing
296
        if (!\is_dir($src)) {
297
            return false;
298
        }
299
        // If the destination directory does not exist and could not be created stop processing
300
        if (!\is_dir(
301
                $dest
302
            )
303
            && !\mkdir(
304
                $dest
305
            )
306
            && !\is_dir(
307
                $dest
308
            )) {
309
            return false;
310
        }
311
        // Open the source directory to read in files
312
        $iterator = new DirectoryIterator($src);
313
        foreach ($iterator as $fObj) {
314
            if ($fObj->isFile()) {
315
                \copy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
316
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
317
                self::rcopy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
318
            }
319
        }
320
321
        return true;
322
    }
323
}
324