1<?php
2
3namespace PhpOffice\PhpSpreadsheet\Shared;
4
5use InvalidArgumentException;
6use ZipArchive;
7
8class File
9{
10    /**
11     * Use Temp or File Upload Temp for temporary files.
12     *
13     * @var bool
14     */
15    protected static $useUploadTempDirectory = false;
16
17    /**
18     * Set the flag indicating whether the File Upload Temp directory should be used for temporary files.
19     *
20     * @param bool $useUploadTempDir Use File Upload Temporary directory (true or false)
21     */
22    public static function setUseUploadTempDirectory($useUploadTempDir)
23    {
24        self::$useUploadTempDirectory = (bool) $useUploadTempDir;
25    }
26
27    /**
28     * Get the flag indicating whether the File Upload Temp directory should be used for temporary files.
29     *
30     * @return bool Use File Upload Temporary directory (true or false)
31     */
32    public static function getUseUploadTempDirectory()
33    {
34        return self::$useUploadTempDirectory;
35    }
36
37    /**
38     * Verify if a file exists.
39     *
40     * @param string $pFilename Filename
41     *
42     * @return bool
43     */
44    public static function fileExists($pFilename)
45    {
46        // Sick construction, but it seems that
47        // file_exists returns strange values when
48        // doing the original file_exists on ZIP archives...
49        if (strtolower(substr($pFilename, 0, 3)) == 'zip') {
50            // Open ZIP file and verify if the file exists
51            $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6);
52            $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1);
53
54            $zip = new ZipArchive();
55            if ($zip->open($zipFile) === true) {
56                $returnValue = ($zip->getFromName($archiveFile) !== false);
57                $zip->close();
58
59                return $returnValue;
60            }
61
62            return false;
63        }
64
65        return file_exists($pFilename);
66    }
67
68    /**
69     * Returns canonicalized absolute pathname, also for ZIP archives.
70     *
71     * @param string $pFilename
72     *
73     * @return string
74     */
75    public static function realpath($pFilename)
76    {
77        // Returnvalue
78        $returnValue = '';
79
80        // Try using realpath()
81        if (file_exists($pFilename)) {
82            $returnValue = realpath($pFilename);
83        }
84
85        // Found something?
86        if ($returnValue == '' || ($returnValue === null)) {
87            $pathArray = explode('/', $pFilename);
88            while (in_array('..', $pathArray) && $pathArray[0] != '..') {
89                $iMax = count($pathArray);
90                for ($i = 0; $i < $iMax; ++$i) {
91                    if ($pathArray[$i] == '..' && $i > 0) {
92                        unset($pathArray[$i], $pathArray[$i - 1]);
93
94                        break;
95                    }
96                }
97            }
98            $returnValue = implode('/', $pathArray);
99        }
100
101        // Return
102        return $returnValue;
103    }
104
105    /**
106     * Get the systems temporary directory.
107     *
108     * @return string
109     */
110    public static function sysGetTempDir()
111    {
112        // Moodle hack!
113        if (function_exists('make_temp_directory')) {
114            $temp = make_temp_directory('phpspreadsheet');
115            return realpath(dirname($temp));
116        }
117
118        if (self::$useUploadTempDirectory) {
119            //  use upload-directory when defined to allow running on environments having very restricted
120            //      open_basedir configs
121            if (ini_get('upload_tmp_dir') !== false) {
122                if ($temp = ini_get('upload_tmp_dir')) {
123                    if (file_exists($temp)) {
124                        return realpath($temp);
125                    }
126                }
127            }
128        }
129
130        return realpath(sys_get_temp_dir());
131    }
132
133    /**
134     * Assert that given path is an existing file and is readable, otherwise throw exception.
135     *
136     * @param string $filename
137     *
138     * @throws InvalidArgumentException
139     */
140    public static function assertFile($filename)
141    {
142        if (!is_file($filename)) {
143            throw new InvalidArgumentException('File "' . $filename . '" does not exist.');
144        }
145
146        if (!is_readable($filename)) {
147            throw new InvalidArgumentException('Could not open "' . $filename . '" for reading.');
148        }
149    }
150}
151