Passed
Push — master ( 4761c2...696f77 )
by
unknown
05:50 queued 19s
created

class/Common/FilesManagement.php (4 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace XoopsModules\Suico\Common;
6
7
/*
8
 You may not change or alter any portion of this comment or credits
9
 of supporting developers from this source code or any supporting source code
10
 which is considered copyrighted (c) material of the original comment or credit authors.
11
12
 This program is distributed in the hope that it will be useful,
13
 but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
 */
16
17
/**
18
 * @category        Module
19
 * @package         suico
20
 * @copyright       {@link https://xoops.org/ XOOPS Project}
21
 * @license         GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
22
 * @author          Marcello Brandão aka  Suico, Mamba, LioMJ  <https://xoops.org>
23
 */
24
25
use DirectoryIterator;
26
use RuntimeException;
27
use SplFileInfo;
28
use Throwable;
29
use XoopsUser;
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
    ) {
43
        try {
44
            if (!\file_exists($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        http://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
        $dir = \dir($source);
123
        if (@\is_dir($dir)) {
124
            while (false !== $entry = $dir->read()) {
125
                // Skip pointers
126
                if ('.' === $entry || '..' === $entry) {
127
                    continue;
128
                }
129
                // Deep copy directories
130
                self::xcopy("${source}/${entry}", "${dest}/${entry}");
131
            }
132
            // Clean up
133
            $dir->close();
134
        }
135
        return true;
136
    }
137
138
    /**
139
     * Remove files and (sub)directories
140
     *
141
     * @param string $src source directory to delete
142
     *
143
     * @return bool true on success
144
     * @uses \Xmf\Module\Helper::isUserAdmin()
145
     *
146
     * @uses \Xmf\Module\Helper::getHelper()
147
     */
148
    public static function deleteDirectory(
149
        $src
150
    ) {
151
        // Only continue if user is a 'global' Admin
152
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
153
            return false;
154
        }
155
        $success = true;
156
        // remove old files
157
        $dirInfo = new SplFileInfo($src);
158
        // validate is a directory
159
        if ($dirInfo->isDir()) {
160
            $fileList = \array_diff(\scandir($src, \SCANDIR_SORT_NONE), ['..', '.']);
161
            foreach ($fileList as $k => $v) {
162
                $fileInfo = new SplFileInfo("{$src}/{$v}");
163
                if ($fileInfo->isDir()) {
164
                    // recursively handle subdirectories
165
                    if (!$success = self::deleteDirectory(
166
                        $fileInfo->getRealPath()
167
                    )) {
168
                        break;
169
                    }
170
                } elseif (!($success = \unlink($fileInfo->getRealPath()))) {
171
                    break;
172
                }
173
            }
174
            // now delete this (sub)directory if all the files are gone
175
            if ($success) {
176
                $success = \rmdir($dirInfo->getRealPath());
177
            }
178
        } else {
179
            // input is not a valid directory
180
            $success = false;
181
        }
182
        return $success;
183
    }
184
185
    /**
186
     * Recursively remove directory
187
     *
188
     * @todo currently won't remove directories with hidden files, should it?
189
     *
190
     * @param string $src directory to remove (delete)
191
     *
192
     * @return bool true on success
193
     */
194
    public static function rrmdir(
195
        $src
196
    ) {
197
        // Only continue if user is a 'global' Admin
198
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
199
            return false;
200
        }
201
        // If source is not a directory stop processing
202
        if (!\is_dir($src)) {
203
            return false;
204
        }
205
        $success = true;
0 ignored issues
show
The assignment to $success is dead and can be removed.
Loading history...
206
        // Open the source directory to read in files
207
        $iterator = new DirectoryIterator($src);
208
        foreach ($iterator as $fObj) {
209
            if ($fObj->isFile()) {
210
                $filename = $fObj->getPathname();
211
                $fObj     = null; // clear this iterator object to close the file
0 ignored issues
show
The assignment to $fObj is dead and can be removed.
Loading history...
212
                if (!\unlink($filename)) {
213
                    return false; // couldn't delete the file
214
                }
215
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
216
                // Try recursively on directory
217
                self::rrmdir($fObj->getPathname());
218
            }
219
        }
220
        $iterator = null;   // clear iterator Obj to close file/directory
0 ignored issues
show
The assignment to $iterator is dead and can be removed.
Loading history...
221
        return \rmdir($src); // remove the directory & return results
222
    }
223
224
    /**
225
     * Recursively move files from one directory to another
226
     *
227
     * @param string $src  - Source of files being moved
228
     * @param string $dest - Destination of files being moved
229
     *
230
     * @return bool true on success
231
     */
232
    public static function rmove(
233
        $src,
234
        $dest
235
    ) {
236
        // Only continue if user is a 'global' Admin
237
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
238
            return false;
239
        }
240
        // If source is not a directory stop processing
241
        if (!\is_dir($src)) {
242
            return false;
243
        }
244
        // If the destination directory does not exist and could not be created stop processing
245
        if (!\is_dir(
246
                $dest
247
            )
248
            && !\mkdir(
249
                $dest
250
            )
251
            && !\is_dir(
252
                $dest
253
            )) {
254
            return false;
255
        }
256
        // Open the source directory to read in files
257
        $iterator = new DirectoryIterator($src);
258
        foreach ($iterator as $fObj) {
259
            if ($fObj->isFile()) {
260
                \rename($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
261
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
262
                // Try recursively on directory
263
                self::rmove($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
264
                //                rmdir($fObj->getPath()); // now delete the directory
265
            }
266
        }
267
        $iterator = null;   // clear iterator Obj to close file/directory
0 ignored issues
show
The assignment to $iterator is dead and can be removed.
Loading history...
268
        return \rmdir($src); // remove the directory & return results
269
    }
270
271
    /**
272
     * Recursively copy directories and files from one directory to another
273
     *
274
     * @param string $src  - Source of files being moved
275
     * @param string $dest - Destination of files being moved
276
     *
277
     * @return bool true on success
278
     * @uses \Xmf\Module\Helper::isUserAdmin()
279
     *
280
     * @uses \Xmf\Module\Helper::getHelper()
281
     */
282
    public static function rcopy(
283
        $src,
284
        $dest
285
    ) {
286
        // Only continue if user is a 'global' Admin
287
        if (!($GLOBALS['xoopsUser'] instanceof XoopsUser) || !$GLOBALS['xoopsUser']->isAdmin()) {
288
            return false;
289
        }
290
        // If source is not a directory stop processing
291
        if (!\is_dir($src)) {
292
            return false;
293
        }
294
        // If the destination directory does not exist and could not be created stop processing
295
        if (!\is_dir(
296
                $dest
297
            )
298
            && !\mkdir(
299
                $dest
300
            )
301
            && !\is_dir(
302
                $dest
303
            )) {
304
            return false;
305
        }
306
        // Open the source directory to read in files
307
        $iterator = new DirectoryIterator($src);
308
        foreach ($iterator as $fObj) {
309
            if ($fObj->isFile()) {
310
                \copy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
311
            } elseif (!$fObj->isDot() && $fObj->isDir()) {
312
                self::rcopy($fObj->getPathname(), "{$dest}/" . $fObj->getFilename());
313
            }
314
        }
315
        return true;
316
    }
317
}
318