Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.07% covered (warning)
85.07%
245 / 288
61.11% covered (warning)
61.11%
11 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
SeedDMS_Core_File
85.07% covered (warning)
85.07%
245 / 288
61.11% covered (warning)
61.11%
11 / 18
79.06
0.00% covered (danger)
0.00%
0 / 1
 renameFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 removeFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 copyFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 linkFile
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 moveFile
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 fileSize
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 mimetype
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
110
 format_filesize
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 parse_filesize
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
8
 file_exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 checksum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fileExtension
100.00% covered (success)
100.00%
189 / 189
100.00% covered (success)
100.00%
1 / 1
7
 renameDir
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 makeDir
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 removeDir
84.62% covered (warning)
84.62%
11 / 13
0.00% covered (danger)
0.00%
0 / 1
8.23
 copyDir
69.23% covered (warning)
69.23%
9 / 13
0.00% covered (danger)
0.00%
0 / 1
9.86
 moveDir
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 gzcompressfile
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2declare(strict_types=1);
3
4/**
5 * Implementation of various file system operations
6 *
7 * @category   DMS
8 * @package    SeedDMS_Core
9 * @license    GPL 2
10 * @version    @version@
11 * @author     Uwe Steinmann <uwe@steinmann.cx>
12 * @copyright  Copyright (C) 2002-2005 Markus Westphal,
13 *             2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli,
14 *             2010-2022 Uwe Steinmann
15 * @version    Release: @package_version@
16 */
17
18/**
19 * Class to file operation in the document management system
20 * Use the methods of this class only for files below the content
21 * directory but not for temporäry files, cache files or log files.
22 *
23 * @category   DMS
24 * @package    SeedDMS_Core
25 * @author     Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
26 * @copyright  Copyright (C) 2002-2005 Markus Westphal,
27 *             2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli,
28 *             2010-2022 Uwe Steinmann
29 * @version    Release: @package_version@
30 */
31class SeedDMS_Core_File {
32    /**
33     * @param $old
34     * @param $new
35     * @return bool
36     */
37    static function renameFile($old, $new) { /* {{{ */
38        return @rename($old, $new);
39    } /* }}} */
40
41    /**
42     * @param $file
43     * @return bool
44     */
45    static function removeFile($file) { /* {{{ */
46        return @unlink($file);
47    } /* }}} */
48
49    /**
50     * @param $source
51     * @param $target
52     * @return bool
53     */
54    static function copyFile($source, $target) { /* {{{ */
55        return @copy($source, $target);
56    } /* }}} */
57
58    /**
59     * @param $source
60     * @param $target
61     * @return bool
62     */
63    static function linkFile($source, $target) { /* {{{ */
64        return symlink($source, $target);
65    } /* }}} */
66
67    /**
68     * @param $source
69     * @param $target
70     * @return bool
71     */
72    static function moveFile($source, $target) { /* {{{ */
73        /** @noinspection PhpUndefinedFunctionInspection */
74        if (!self::copyFile($source, $target))
75            return false;
76        /** @noinspection PhpUndefinedFunctionInspection */
77        return self::removeFile($source);
78    } /* }}} */
79
80    /**
81     * @param $file
82     * @return bool|int
83     */
84    static function fileSize($file) { /* {{{ */
85        if(!$a = @fopen($file, 'r'))
86            return false;
87        fseek($a, 0, SEEK_END);
88        $filesize = ftell($a);
89        fclose($a);
90        return $filesize;
91    } /* }}} */
92
93    /**
94     * Return the mimetype of a given file
95     *
96     * This method uses finfo to determine the mimetype
97     * but will correct some mimetypes which are
98     * not propperly determined or could be more specific, e.g. text/plain
99     * when it is actually text/markdown. In thoses cases
100     * the file extension will be taken into account.
101     *
102     * @param string $filename name of file on disc
103     * @return string mimetype
104     */
105    static function mimetype($filename) { /* {{{ */
106        $finfo = finfo_open(FILEINFO_MIME_TYPE);
107        $mimetype = finfo_file($finfo, $filename);
108
109        $lastDotIndex = strrpos($filename, ".");
110        if($lastDotIndex === false) $fileType = ".";
111        else $fileType = substr($filename, $lastDotIndex);
112
113        switch($mimetype) {
114        case 'application/octet-stream':
115        case 'text/plain':
116            if($fileType == '.md')
117                $mimetype = 'text/markdown';
118            elseif($fileType == '.tex')
119                $mimetype = 'text/x-tex';
120            elseif($fileType == '.docx')
121                $mimetype = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
122            elseif($fileType == '.pkpass')
123                $mimetype = 'application/vnd.apple.pkpass';
124            break;
125        case 'application/zip':
126            if($fileType == '.pkpass')
127                $mimetype = 'application/vnd.apple.pkpass';
128            break;
129        }
130        return $mimetype;
131    } /* }}} */
132
133    /**
134     * @param integer $size
135     * @param array $sizes list of units for 10^0, 10^3, 10^6, ..., 10^(n*3) bytes
136     * @return string
137     */
138    static function format_filesize($size, $sizes = array('Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')) { /* {{{ */
139        if ($size == 0) return('0 Bytes');
140        if ($size == 1) return('1 Byte');
141        /** @noinspection PhpIllegalArrayKeyTypeInspection */
142        return (round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $sizes[$i]);
143    } /* }}} */
144
145    /**
146     * Parses a string like '[0-9]+ *[BKMGT]*' into an integer
147     * B,K,M,G,T stand for byte, kilo byte, mega byte, giga byte, tera byte
148     * If the last character is omitted, bytes are assumed.
149     *
150     * @param $str
151     * @return bool|int
152     */
153    static function parse_filesize($str) { /* {{{ */
154        if(!preg_match('/^([0-9]+) *([BKMGT]*)$/', trim($str), $matches))
155            return false;
156        $value = $matches[1];
157        $unit = $matches[2] ? $matches[2] : 'B';
158        switch($unit) {
159            case 'T':
160                return $value * 1024 * 1024 * 1024 *1024;
161                break;
162            case 'G':
163                return $value * 1024 * 1024 * 1024;
164                break;
165            case 'M':
166                return $value * 1024 * 1024;
167                break;
168            case 'K':
169                return $value * 1024;
170                break;
171            default;
172                return (int) $value;
173                break;
174        }
175        /** @noinspection PhpUnreachableStatementInspection */
176        return false;
177    } /* }}} */
178
179    /**
180     * @param $file
181     * @return string
182     */
183    static function file_exists($file) { /* {{{ */
184        return file_exists($file);
185    } /* }}} */
186
187    /**
188     * @param $file
189     * @return string
190     */
191    static function checksum($file) { /* {{{ */
192        return md5_file($file);
193    } /* }}} */
194
195    /**
196     * @param $string mimetype
197     * @return string file extension with the dot or an empty string
198     */
199    static function fileExtension($mimetype) { /* {{{ */
200        switch($mimetype) {
201        case "application/pdf":
202        case "image/png":
203        case "image/gif":
204        case "image/jpg":
205            $expect = substr($mimetype, -3, 3);
206            break;
207        default:
208            $mime_map = [
209                'video/3gpp2'                                                               => '3g2',
210                'video/3gp'                                                                 => '3gp',
211                'video/3gpp'                                                                => '3gp',
212                'application/x-compressed'                                                  => '7zip',
213                'audio/x-acc'                                                               => 'aac',
214                'audio/ac3'                                                                 => 'ac3',
215                'application/postscript'                                                    => 'ai',
216                'audio/x-aiff'                                                              => 'aif',
217                'audio/aiff'                                                                => 'aif',
218                'audio/x-au'                                                                => 'au',
219                'video/x-msvideo'                                                           => 'avi',
220                'video/msvideo'                                                             => 'avi',
221                'video/avi'                                                                 => 'avi',
222                'application/x-troff-msvideo'                                               => 'avi',
223                'application/macbinary'                                                     => 'bin',
224                'application/mac-binary'                                                    => 'bin',
225                'application/x-binary'                                                      => 'bin',
226                'application/x-macbinary'                                                   => 'bin',
227                'image/bmp'                                                                 => 'bmp',
228                'image/x-bmp'                                                               => 'bmp',
229                'image/x-bitmap'                                                            => 'bmp',
230                'image/x-xbitmap'                                                           => 'bmp',
231                'image/x-win-bitmap'                                                        => 'bmp',
232                'image/x-windows-bmp'                                                       => 'bmp',
233                'image/ms-bmp'                                                              => 'bmp',
234                'image/x-ms-bmp'                                                            => 'bmp',
235                'application/bmp'                                                           => 'bmp',
236                'application/x-bmp'                                                         => 'bmp',
237                'application/x-win-bitmap'                                                  => 'bmp',
238                'application/cdr'                                                           => 'cdr',
239                'application/coreldraw'                                                     => 'cdr',
240                'application/x-cdr'                                                         => 'cdr',
241                'application/x-coreldraw'                                                   => 'cdr',
242                'image/cdr'                                                                 => 'cdr',
243                'image/x-cdr'                                                               => 'cdr',
244                'zz-application/zz-winassoc-cdr'                                            => 'cdr',
245                'application/mac-compactpro'                                                => 'cpt',
246                'application/pkix-crl'                                                      => 'crl',
247                'application/pkcs-crl'                                                      => 'crl',
248                'application/x-x509-ca-cert'                                                => 'crt',
249                'application/pkix-cert'                                                     => 'crt',
250                'text/css'                                                                  => 'css',
251                'text/x-comma-separated-values'                                             => 'csv',
252                'text/comma-separated-values'                                               => 'csv',
253                'application/vnd.msexcel'                                                   => 'csv',
254                'application/x-director'                                                    => 'dcr',
255                'application/vnd.openxmlformats-officedocument.wordprocessingml.document'   => 'docx',
256                'application/x-dvi'                                                         => 'dvi',
257                'message/rfc822'                                                            => 'eml',
258                'application/x-msdownload'                                                  => 'exe',
259                'video/x-f4v'                                                               => 'f4v',
260                'audio/x-flac'                                                              => 'flac',
261                'video/x-flv'                                                               => 'flv',
262                'image/gif'                                                                 => 'gif',
263                'application/gpg-keys'                                                      => 'gpg',
264                'application/x-gtar'                                                        => 'gtar',
265                'application/x-gzip'                                                        => 'gzip',
266                'application/mac-binhex40'                                                  => 'hqx',
267                'application/mac-binhex'                                                    => 'hqx',
268                'application/x-binhex40'                                                    => 'hqx',
269                'application/x-mac-binhex40'                                                => 'hqx',
270                'text/html'                                                                 => 'html',
271                'image/x-icon'                                                              => 'ico',
272                'image/x-ico'                                                               => 'ico',
273                'image/vnd.microsoft.icon'                                                  => 'ico',
274                'text/calendar'                                                             => 'ics',
275                'application/java-archive'                                                  => 'jar',
276                'application/x-java-application'                                            => 'jar',
277                'application/x-jar'                                                         => 'jar',
278                'image/jp2'                                                                 => 'jp2',
279                'video/mj2'                                                                 => 'jp2',
280                'image/jpx'                                                                 => 'jp2',
281                'image/jpm'                                                                 => 'jp2',
282                'image/jpeg'                                                                => 'jpeg',
283                'image/pjpeg'                                                               => 'jpeg',
284                'application/x-javascript'                                                  => 'js',
285                'application/json'                                                          => 'json',
286                'text/json'                                                                 => 'json',
287                'application/vnd.google-earth.kml+xml'                                      => 'kml',
288                'application/vnd.google-earth.kmz'                                          => 'kmz',
289                'text/x-log'                                                                => 'log',
290                'audio/x-m4a'                                                               => 'm4a',
291                'application/vnd.mpegurl'                                                   => 'm4u',
292                'text/markdown'                                                             => 'md',
293                'audio/midi'                                                                => 'mid',
294                'application/vnd.mif'                                                       => 'mif',
295                'video/quicktime'                                                           => 'mov',
296                'video/x-sgi-movie'                                                         => 'movie',
297                'audio/mpeg'                                                                => 'mp3',
298                'audio/mpg'                                                                 => 'mp3',
299                'audio/mpeg3'                                                               => 'mp3',
300                'audio/mp3'                                                                 => 'mp3',
301                'video/mp4'                                                                 => 'mp4',
302                'video/mpeg'                                                                => 'mpeg',
303                'application/oda'                                                           => 'oda',
304                'audio/ogg'                                                                 => 'ogg',
305                'video/ogg'                                                                 => 'ogg',
306                'application/ogg'                                                           => 'ogg',
307                'application/x-pkcs10'                                                      => 'p10',
308                'application/pkcs10'                                                        => 'p10',
309                'application/x-pkcs12'                                                      => 'p12',
310                'application/x-pkcs7-signature'                                             => 'p7a',
311                'application/pkcs7-mime'                                                    => 'p7c',
312                'application/x-pkcs7-mime'                                                  => 'p7c',
313                'application/x-pkcs7-certreqresp'                                           => 'p7r',
314                'application/pkcs7-signature'                                               => 'p7s',
315                'application/pdf'                                                           => 'pdf',
316                'application/octet-stream'                                                  => 'pdf',
317                'application/x-x509-user-cert'                                              => 'pem',
318                'application/x-pem-file'                                                    => 'pem',
319                'application/pgp'                                                           => 'pgp',
320                'application/x-httpd-php'                                                   => 'php',
321                'application/php'                                                           => 'php',
322                'application/x-php'                                                         => 'php',
323                'text/php'                                                                  => 'php',
324                'text/x-php'                                                                => 'php',
325                'application/x-httpd-php-source'                                            => 'php',
326                'image/png'                                                                 => 'png',
327                'image/x-png'                                                               => 'png',
328                'application/powerpoint'                                                    => 'ppt',
329                'application/vnd.ms-powerpoint'                                             => 'ppt',
330                'application/vnd.ms-office'                                                 => 'ppt',
331                'application/msword'                                                        => 'doc',
332                'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
333                'application/x-photoshop'                                                   => 'psd',
334                'image/vnd.adobe.photoshop'                                                 => 'psd',
335                'audio/x-realaudio'                                                         => 'ra',
336                'audio/x-pn-realaudio'                                                      => 'ram',
337                'application/x-rar'                                                         => 'rar',
338                'application/rar'                                                           => 'rar',
339                'application/x-rar-compressed'                                              => 'rar',
340                'audio/x-pn-realaudio-plugin'                                               => 'rpm',
341                'application/x-pkcs7'                                                       => 'rsa',
342                'text/rtf'                                                                  => 'rtf',
343                'text/richtext'                                                             => 'rtx',
344                'video/vnd.rn-realvideo'                                                    => 'rv',
345                'application/x-stuffit'                                                     => 'sit',
346                'application/smil'                                                          => 'smil',
347                'text/srt'                                                                  => 'srt',
348                'image/svg+xml'                                                             => 'svg',
349                'application/x-shockwave-flash'                                             => 'swf',
350                'application/x-tar'                                                         => 'tar',
351                'application/x-gzip-compressed'                                             => 'tgz',
352                'image/tiff'                                                                => 'tiff',
353                'text/plain'                                                                => 'txt',
354                'text/x-vcard'                                                              => 'vcf',
355                'application/videolan'                                                      => 'vlc',
356                'text/vtt'                                                                  => 'vtt',
357                'audio/x-wav'                                                               => 'wav',
358                'audio/wave'                                                                => 'wav',
359                'audio/wav'                                                                 => 'wav',
360                'application/wbxml'                                                         => 'wbxml',
361                'video/webm'                                                                => 'webm',
362                'audio/x-ms-wma'                                                            => 'wma',
363                'application/wmlc'                                                          => 'wmlc',
364                'video/x-ms-wmv'                                                            => 'wmv',
365                'video/x-ms-asf'                                                            => 'wmv',
366                'application/xhtml+xml'                                                     => 'xhtml',
367                'application/excel'                                                         => 'xl',
368                'application/msexcel'                                                       => 'xls',
369                'application/x-msexcel'                                                     => 'xls',
370                'application/x-ms-excel'                                                    => 'xls',
371                'application/x-excel'                                                       => 'xls',
372                'application/x-dos_ms_excel'                                                => 'xls',
373                'application/xls'                                                           => 'xls',
374                'application/x-xls'                                                         => 'xls',
375                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'         => 'xlsx',
376                'application/vnd.ms-excel'                                                  => 'xlsx',
377                'application/xml'                                                           => 'xml',
378                'text/xml'                                                                  => 'xml',
379                'text/xsl'                                                                  => 'xsl',
380                'application/xspf+xml'                                                      => 'xspf',
381                'application/x-compress'                                                    => 'z',
382                'application/x-zip'                                                         => 'zip',
383                'application/zip'                                                           => 'zip',
384                'application/x-zip-compressed'                                              => 'zip',
385                'application/s-compressed'                                                  => 'zip',
386                'multipart/x-zip'                                                           => 'zip',
387                'text/x-scriptzsh'                                                          => 'zsh',
388            ];
389            $expect = isset($mime_map[$mimetype]) === true ? $mime_map[$mimetype] : '';
390        }
391        return $expect;
392    } /* }}} */
393
394    /**
395     * @param $old
396     * @param $new
397     * @return bool
398     */
399    static function renameDir($old, $new) { /* {{{ */
400        return @rename($old, $new);
401    } /* }}} */
402
403    /**
404     * @param $path
405     * @return bool
406     */
407    static function makeDir($path) { /* {{{ */
408        
409        if( !is_dir( $path ) ){
410            $res=@mkdir( $path , 0777, true);
411            if (!$res) return false;
412        }
413
414        return true;
415
416/* some old code 
417        if (strncmp($path, DIRECTORY_SEPARATOR, 1) == 0) {
418            $mkfolder = DIRECTORY_SEPARATOR;
419        }
420        else {
421            $mkfolder = "";
422        }
423        $path = preg_split( "/[\\\\\/]/" , $path );
424        for(  $i=0 ; isset( $path[$i] ) ; $i++ )
425        {
426            if(!strlen(trim($path[$i])))continue;
427            $mkfolder .= $path[$i];
428
429            if( !is_dir( $mkfolder ) ){
430                $res=@mkdir( "$mkfolder" ,  0777);
431                if (!$res) return false;
432            }
433            $mkfolder .= DIRECTORY_SEPARATOR;
434        }
435
436        return true;
437
438        // patch from alekseynfor safe_mod or open_basedir
439
440        global $settings;
441        $path = substr_replace ($path, "/", 0, strlen($settings->_contentDir));
442        $mkfolder = $settings->_contentDir;
443
444        $path = preg_split( "/[\\\\\/]/" , $path );
445
446        for(  $i=0 ; isset( $path[$i] ) ; $i++ )
447        {
448            if(!strlen(trim($path[$i])))continue;
449            $mkfolder .= $path[$i];
450
451            if( !is_dir( $mkfolder ) ){
452                $res= @mkdir( "$mkfolder" ,  0777);
453                if (!$res) return false;
454            }
455            $mkfolder .= DIRECTORY_SEPARATOR;
456        }
457
458        return true;
459*/
460    } /* }}} */
461
462    /**
463     * @param $path
464     * @return bool
465     */
466    static function removeDir($path) { /* {{{ */
467        $handle = @opendir($path);
468        if(!$handle)
469            return false;
470        while ($entry = @readdir($handle) )
471        {
472            if ($entry == ".." || $entry == ".")
473                continue;
474            else if (is_dir($path . DIRECTORY_SEPARATOR . $entry))
475            {
476                if (!self::removeDir($path . DIRECTORY_SEPARATOR . $entry ))
477                    return false;
478            }
479            else
480            {
481                if (!@unlink($path . DIRECTORY_SEPARATOR . $entry))
482                    return false;
483            }
484        }
485        @closedir($handle);
486        return @rmdir($path);
487    } /* }}} */
488
489    /**
490     * @param $sourcePath
491     * @param $targetPath
492     * @return bool
493     */
494    static function copyDir($sourcePath, $targetPath) { /* {{{ */
495        if (mkdir($targetPath, 0777)) {
496            $handle = @opendir($sourcePath);
497            while ($entry = @readdir($handle) ) {
498                if ($entry == ".." || $entry == ".")
499                    continue;
500                else if (is_dir($sourcePath . $entry)) {
501                    if (!self::copyDir($sourcePath . DIRECTORY_SEPARATOR . $entry, $targetPath . DIRECTORY_SEPARATOR . $entry))
502                        return false;
503                } else {
504                    if (!@copy($sourcePath . DIRECTORY_SEPARATOR . $entry, $targetPath . DIRECTORY_SEPARATOR . $entry))
505                        return false;
506                }
507            }
508            @closedir($handle);
509        }
510        else
511            return false;
512
513        return true;
514    } /* }}} */
515
516    /**
517     * @param $sourcePath
518     * @param $targetPath
519     * @return bool
520     */
521    static function moveDir($sourcePath, $targetPath) { /* {{{ */
522        /** @noinspection PhpUndefinedFunctionInspection */
523        if (!self::copyDir($sourcePath, $targetPath))
524            return false;
525        /** @noinspection PhpUndefinedFunctionInspection */
526        return self::removeDir($sourcePath);
527    } /* }}} */
528
529    // code by Kioob (php.net manual)
530    /**
531     * @param $source
532     * @param bool $level
533     * @return bool|string
534     */
535    static function gzcompressfile($source, $level=false) { /* {{{ */
536        $dest=$source.'.gz';
537        $mode='wb'.$level;
538        $error=false;
539        if($fp_out=@gzopen($dest,$mode)) {
540            if($fp_in=@fopen($source,'rb')) {
541                while(!feof($fp_in))
542                    @gzwrite($fp_out,fread($fp_in,1024*512));
543                @fclose($fp_in);
544            }
545            else $error=true;
546            @gzclose($fp_out);
547        }
548        else $error=true;
549
550        if($error) return false;
551        else return $dest;
552    } /* }}} */
553}