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