Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
<?php

namespace PhpOffice\PhpSpreadsheet\Shared;

< use InvalidArgumentException;
> use PhpOffice\PhpSpreadsheet\Exception; > use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
use ZipArchive; class File { /** * Use Temp or File Upload Temp for temporary files. * * @var bool */ protected static $useUploadTempDirectory = false; /** * Set the flag indicating whether the File Upload Temp directory should be used for temporary files.
< * < * @param bool $useUploadTempDir Use File Upload Temporary directory (true or false)
*/
< public static function setUseUploadTempDirectory($useUploadTempDir): void
> public static function setUseUploadTempDirectory(bool $useUploadTempDir): void
{ self::$useUploadTempDirectory = (bool) $useUploadTempDir; } /** * Get the flag indicating whether the File Upload Temp directory should be used for temporary files.
< * < * @return bool Use File Upload Temporary directory (true or false)
*/
< public static function getUseUploadTempDirectory()
> public static function getUseUploadTempDirectory(): bool
{ return self::$useUploadTempDirectory; }
> // https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT /** > // Section 4.3.7 * Verify if a file exists. > // Looks like there might be endian-ness considerations * > private const ZIP_FIRST_4 = [ * @param string $pFilename Filename > "\x50\x4b\x03\x04", // what it looks like on my system * > "\x04\x03\x4b\x50", // what it says in documentation * @return bool > ]; */ > public static function fileExists($pFilename) > private static function validateZipFirst4(string $zipFile): bool { > { // Sick construction, but it seems that > $contents = @file_get_contents($zipFile, false, null, 0, 4); // file_exists returns strange values when > // doing the original file_exists on ZIP archives... > return in_array($contents, self::ZIP_FIRST_4, true); if (strtolower(substr($pFilename, 0, 3)) == 'zip') { > } // Open ZIP file and verify if the file exists >
< * < * @param string $pFilename Filename < * < * @return bool
< public static function fileExists($pFilename)
> public static function fileExists(string $filename): bool
< if (strtolower(substr($pFilename, 0, 3)) == 'zip') {
> if (strtolower(substr($filename, 0, 6)) == 'zip://') {
< $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); < $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1);
> $zipFile = substr($filename, 6, strrpos($filename, '#') - 6); > $archiveFile = substr($filename, strrpos($filename, '#') + 1);
return $returnValue;
> if (self::validateZipFirst4($zipFile)) {
< if ($zip->open($zipFile) === true) {
> $res = $zip->open($zipFile); > if ($res === true) {
> }
return false; }
< return file_exists($pFilename);
> return file_exists($filename);
} /** * Returns canonicalized absolute pathname, also for ZIP archives.
< * < * @param string $pFilename < * < * @return string
*/
< public static function realpath($pFilename)
> public static function realpath(string $filename): string
{ // Returnvalue $returnValue = ''; // Try using realpath()
< if (file_exists($pFilename)) { < $returnValue = realpath($pFilename);
> if (file_exists($filename)) { > $returnValue = realpath($filename) ?: '';
} // Found something?
< if ($returnValue == '' || ($returnValue === null)) { < $pathArray = explode('/', $pFilename);
> if ($returnValue === '') { > $pathArray = explode('/', $filename);
while (in_array('..', $pathArray) && $pathArray[0] != '..') { $iMax = count($pathArray); for ($i = 0; $i < $iMax; ++$i) { if ($pathArray[$i] == '..' && $i > 0) { unset($pathArray[$i], $pathArray[$i - 1]); break; } } } $returnValue = implode('/', $pathArray); } // Return return $returnValue; } /** * Get the systems temporary directory.
< * < * @return string
*/
< public static function sysGetTempDir()
> public static function sysGetTempDir(): string
{ // Moodle hack! if (function_exists('make_temp_directory')) { $temp = make_temp_directory('phpspreadsheet'); return realpath(dirname($temp)); }
> $path = sys_get_temp_dir();
if (self::$useUploadTempDirectory) { // use upload-directory when defined to allow running on environments having very restricted // open_basedir configs if (ini_get('upload_tmp_dir') !== false) { if ($temp = ini_get('upload_tmp_dir')) { if (file_exists($temp)) {
< return realpath($temp);
> $path = $temp; > }
} } }
> } > return realpath($path) ?: ''; > } return realpath(sys_get_temp_dir()); > } > public static function temporaryFilename(): string > { /** > $filename = tempnam(self::sysGetTempDir(), 'phpspreadsheet'); * Assert that given path is an existing file and is readable, otherwise throw exception. > if ($filename === false) { * > throw new Exception('Could not create temporary file');
< return realpath(sys_get_temp_dir());
> return $filename;
< * < * @param string $filename
< public static function assertFile($filename): void
> public static function assertFile(string $filename, string $zipMember = ''): void
if (!is_file($filename)) {
< throw new InvalidArgumentException('File "' . $filename . '" does not exist.');
> throw new ReaderException('File "' . $filename . '" does not exist.');
} if (!is_readable($filename)) {
< throw new InvalidArgumentException('Could not open "' . $filename . '" for reading.');
> throw new ReaderException('Could not open "' . $filename . '" for reading.'); > } > > if ($zipMember !== '') { > $zipfile = "zip://$filename#$zipMember"; > if (!self::fileExists($zipfile)) { > throw new ReaderException("Could not find zip member $zipfile"); > } > } > } > > /** > * Same as assertFile, except return true/false and don't throw Exception. > */ > public static function testFileNoThrow(string $filename, ?string $zipMember = null): bool > { > if (!is_file($filename)) { > return false; > } > if (!is_readable($filename)) { > return false; > } > if ($zipMember === null) { > return true;
}
> // validate zip, but don't check specific member } > if ($zipMember === '') { } > return self::validateZipFirst4($filename); > } > > return self::fileExists("zip://$filename#$zipMember");