Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Shared;
4
 
5
use PhpOffice\PhpSpreadsheet\Exception;
6
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
7
use ZipArchive;
8
 
9
class File
10
{
11
    /**
12
     * Use Temp or File Upload Temp for temporary files.
13
     */
14
    protected static bool $useUploadTempDirectory = false;
15
 
16
    /**
17
     * Set the flag indicating whether the File Upload Temp directory should be used for temporary files.
18
     */
19
    public static function setUseUploadTempDirectory(bool $useUploadTempDir): void
20
    {
21
        self::$useUploadTempDirectory = (bool) $useUploadTempDir;
22
    }
23
 
24
    /**
25
     * Get the flag indicating whether the File Upload Temp directory should be used for temporary files.
26
     */
27
    public static function getUseUploadTempDirectory(): bool
28
    {
29
        return self::$useUploadTempDirectory;
30
    }
31
 
32
    // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
33
    // Section 4.3.7
34
    // Looks like there might be endian-ness considerations
35
    private const ZIP_FIRST_4 = [
36
        "\x50\x4b\x03\x04", // what it looks like on my system
37
        "\x04\x03\x4b\x50", // what it says in documentation
38
    ];
39
 
40
    private static function validateZipFirst4(string $zipFile): bool
41
    {
42
        $contents = @file_get_contents($zipFile, false, null, 0, 4);
43
 
44
        return in_array($contents, self::ZIP_FIRST_4, true);
45
    }
46
 
47
    /**
48
     * Verify if a file exists.
49
     */
50
    public static function fileExists(string $filename): bool
51
    {
52
        // Sick construction, but it seems that
53
        // file_exists returns strange values when
54
        // doing the original file_exists on ZIP archives...
55
        if (strtolower(substr($filename, 0, 6)) == 'zip://') {
56
            // Open ZIP file and verify if the file exists
57
            $zipFile = substr($filename, 6, strrpos($filename, '#') - 6);
58
            $archiveFile = substr($filename, strrpos($filename, '#') + 1);
59
 
60
            if (self::validateZipFirst4($zipFile)) {
61
                $zip = new ZipArchive();
62
                $res = $zip->open($zipFile);
63
                if ($res === true) {
64
                    $returnValue = ($zip->getFromName($archiveFile) !== false);
65
                    $zip->close();
66
 
67
                    return $returnValue;
68
                }
69
            }
70
 
71
            return false;
72
        }
73
 
74
        return file_exists($filename);
75
    }
76
 
77
    /**
78
     * Returns canonicalized absolute pathname, also for ZIP archives.
79
     */
80
    public static function realpath(string $filename): string
81
    {
82
        // Returnvalue
83
        $returnValue = '';
84
 
85
        // Try using realpath()
86
        if (file_exists($filename)) {
87
            $returnValue = realpath($filename) ?: '';
88
        }
89
 
90
        // Found something?
91
        if ($returnValue === '') {
92
            $pathArray = explode('/', $filename);
93
            while (in_array('..', $pathArray) && $pathArray[0] != '..') {
94
                $iMax = count($pathArray);
95
                for ($i = 1; $i < $iMax; ++$i) {
96
                    if ($pathArray[$i] == '..') {
97
                        array_splice($pathArray, $i - 1, 2);
98
 
99
                        break;
100
                    }
101
                }
102
            }
103
            $returnValue = implode('/', $pathArray);
104
        }
105
 
106
        // Return
107
        return $returnValue;
108
    }
109
 
110
    /**
111
     * Get the systems temporary directory.
112
     */
113
    public static function sysGetTempDir(): string
114
    {
115
        // Moodle hack!
116
        if (function_exists('make_temp_directory')) {
117
            $temp = make_temp_directory('phpspreadsheet');
118
            return realpath(dirname($temp));
119
        }
120
 
121
        $path = sys_get_temp_dir();
122
        if (self::$useUploadTempDirectory) {
123
            //  use upload-directory when defined to allow running on environments having very restricted
124
            //      open_basedir configs
125
            if (ini_get('upload_tmp_dir') !== false) {
126
                if ($temp = ini_get('upload_tmp_dir')) {
127
                    if (file_exists($temp)) {
128
                        $path = $temp;
129
                    }
130
                }
131
            }
132
        }
133
 
134
        return realpath($path) ?: '';
135
    }
136
 
137
    public static function temporaryFilename(): string
138
    {
139
        $filename = tempnam(self::sysGetTempDir(), 'phpspreadsheet');
140
        if ($filename === false) {
141
            throw new Exception('Could not create temporary file');
142
        }
143
 
144
        return $filename;
145
    }
146
 
147
    /**
148
     * Assert that given path is an existing file and is readable, otherwise throw exception.
149
     */
150
    public static function assertFile(string $filename, string $zipMember = ''): void
151
    {
152
        if (!is_file($filename)) {
153
            throw new ReaderException('File "' . $filename . '" does not exist.');
154
        }
155
 
156
        if (!is_readable($filename)) {
157
            throw new ReaderException('Could not open "' . $filename . '" for reading.');
158
        }
159
 
160
        if ($zipMember !== '') {
161
            $zipfile = "zip://$filename#$zipMember";
162
            if (!self::fileExists($zipfile)) {
163
                // Has the file been saved with Windoze directory separators rather than unix?
164
                $zipfile = "zip://$filename#" . str_replace('/', '\\', $zipMember);
165
                if (!self::fileExists($zipfile)) {
166
                    throw new ReaderException("Could not find zip member $zipfile");
167
                }
168
            }
169
        }
170
    }
171
 
172
    /**
173
     * Same as assertFile, except return true/false and don't throw Exception.
174
     */
175
    public static function testFileNoThrow(string $filename, ?string $zipMember = null): bool
176
    {
177
        if (!is_file($filename)) {
178
            return false;
179
        }
180
        if (!is_readable($filename)) {
181
            return false;
182
        }
183
        if ($zipMember === null) {
184
            return true;
185
        }
186
        // validate zip, but don't check specific member
187
        if ($zipMember === '') {
188
            return self::validateZipFirst4($filename);
189
        }
190
 
191
        $zipfile = "zip://$filename#$zipMember";
192
        if (self::fileExists($zipfile)) {
193
            return true;
194
        }
195
 
196
        // Has the file been saved with Windoze directory separators rather than unix?
197
        $zipfile = "zip://$filename#" . str_replace('/', '\\', $zipMember);
198
 
199
        return self::fileExists($zipfile);
200
    }
201
}