From 1e00a050d72c1f730b29bd4cd9fbc6108871e3f0 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 10 Dec 2017 16:31:42 +0300 Subject: [PATCH] Fixes #15322: Fixed PHP 7.2 compatibility of `FileHelper::getExtensionsByMimeType()` --- build/controllers/MimeTypeController.php | 92 +++++++++++++++++------- build/controllers/ReleaseController.php | 4 +- framework/CHANGELOG.md | 1 + framework/helpers/BaseFileHelper.php | 33 +++++++++ framework/helpers/mimeAliases.php | 9 +++ tests/framework/validators/FileValidatorTest.php | 9 +-- 6 files changed, 116 insertions(+), 32 deletions(-) create mode 100644 framework/helpers/mimeAliases.php diff --git a/build/controllers/MimeTypeController.php b/build/controllers/MimeTypeController.php index 8faf653..2724451 100644 --- a/build/controllers/MimeTypeController.php +++ b/build/controllers/MimeTypeController.php @@ -27,34 +27,60 @@ use yii\helpers\VarDumper; class MimeTypeController extends Controller { /** - * @param string $outFile the file to update. Defaults to @yii/helpers/mimeTypes.php + * @var array MIME type aliases */ - public function actionIndex($outFile = null) + private $aliases = [ + 'text/xml' => 'application/xml', + ]; + + /** + * @param string $outFile the mime file to update. Defaults to @yii/helpers/mimeTypes.php + * @param string $aliasesOutFile the aliases file to update. Defaults to @yii/helpers/mimeAliases.php + */ + public function actionIndex($outFile = null, $aliasesOutFile = null) { if ($outFile === null) { $outFile = Yii::getAlias('@yii/helpers/mimeTypes.php'); } + + if ($aliasesOutFile === null) { + $aliasesOutFile = Yii::getAlias('@yii/helpers/mimeAliases.php'); + } + $this->stdout('downloading mime-type file from apache httpd repository...'); - if ($content = file_get_contents('http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co')) { + if ($apacheMimeTypesFileContent = file_get_contents('http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co')) { $this->stdout("done.\n", Console::FG_GREEN); - $this->stdout("generating file $outFile..."); - $mimeMap = []; - foreach (explode("\n", $content) as $line) { - $line = trim($line); - if (empty($line) || $line[0] == '#') { // skip comments and empty lines - continue; - } - $parts = preg_split('/\s+/', $line); - $mime = array_shift($parts); - foreach ($parts as $ext) { - if (!empty($ext)) { - $mimeMap[$ext] = $mime; - } + $this->generateMimeTypesFile($outFile, $apacheMimeTypesFileContent); + $this->generateMimeAliasesFile($aliasesOutFile); + } else { + $this->stderr("Failed to download mime.types file from apache SVN.\n"); + } + } + + /** + * @param string $outFile + * @param string $content + */ + private function generateMimeTypesFile($outFile, $content) + { + $this->stdout("generating file $outFile..."); + $mimeMap = []; + foreach (explode("\n", $content) as $line) { + $line = trim($line); + if (empty($line) || $line[0] === '#') { // skip comments and empty lines + continue; + } + $parts = preg_split('/\s+/', $line); + $mime = array_shift($parts); + foreach ($parts as $ext) { + if (!empty($ext)) { + $mimeMap[$ext] = $mime; } } - ksort($mimeMap); - $array = VarDumper::export($mimeMap); - $content = <<stdout("done.\n", Console::FG_GREEN); - } else { - $this->stderr("Failed to download mime.types file from apache SVN.\n"); - } + file_put_contents($outFile, $content); + $this->stdout("done.\n", Console::FG_GREEN); + } + + /** + * @param string $outFile + */ + private function generateMimeAliasesFile($outFile) + { + $this->stdout("generating file $outFile..."); + $array = VarDumper::export($this->aliases); + $content = <<stdout("done.\n", Console::FG_GREEN); } } diff --git a/build/controllers/ReleaseController.php b/build/controllers/ReleaseController.php index 985f1e7..582e7cc 100644 --- a/build/controllers/ReleaseController.php +++ b/build/controllers/ReleaseController.php @@ -433,8 +433,8 @@ class ReleaseController extends Controller $this->dryRun || Yii::$app->runAction('classmap', [$frameworkPath]); $this->stdout("done.\n", Console::FG_GREEN, Console::BOLD); - $this->stdout('updating mimetype magic file...', Console::BOLD); - $this->dryRun || Yii::$app->runAction('mime-type', ["$frameworkPath/helpers/mimeTypes.php"]); + $this->stdout('updating mimetype magic file and mime aliases...', Console::BOLD); + $this->dryRun || Yii::$app->runAction('mime-type', ["$frameworkPath/helpers/mimeTypes.php"], ["$frameworkPath/helpers/mimeAliases.php"]); $this->stdout("done.\n", Console::FG_GREEN, Console::BOLD); $this->stdout("fixing various PHPDoc style issues...\n", Console::BOLD); diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 19df2ab..d033eb6 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -24,6 +24,7 @@ Yii Framework 2 Change Log - Bug #15270: Resolved potential race conditions when writing generated php-files (kalessil) - Bug #15302: Fixed `yii\caching\DbCache` so that `getValues` now behaves the same as `getValue` with regards to streams (edwards-sj) - Bug #15301: Fixed `ArrayHelper::filter()` to work properly with `0` in values (hhniao) +- Bug #15322: Fixed PHP 7.2 compatibility of `FileHelper::getExtensionsByMimeType()` (samdark) 2.0.13.1 November 14, 2017 -------------------------- diff --git a/framework/helpers/BaseFileHelper.php b/framework/helpers/BaseFileHelper.php index a92d4c9..494b6ef 100644 --- a/framework/helpers/BaseFileHelper.php +++ b/framework/helpers/BaseFileHelper.php @@ -34,6 +34,12 @@ class BaseFileHelper */ public static $mimeMagicFile = '@yii/helpers/mimeTypes.php'; + /** + * @var string the path (or alias) of a PHP file containing MIME aliases. + * @since 2.0.14 + */ + public static $mimeAliasesFile = '@yii/helpers/mimeAliases.php'; + /** * Normalizes a file/directory path. @@ -189,6 +195,11 @@ class BaseFileHelper */ public static function getExtensionsByMimeType($mimeType, $magicFile = null) { + $aliases = static::loadMimeAliases(static::$mimeAliasesFile); + if (isset($aliases[$mimeType])) { + $mimeType = $aliases[$mimeType]; + } + $mimeTypes = static::loadMimeTypes($magicFile); return array_keys($mimeTypes, mb_strtolower($mimeType, 'UTF-8'), true); } @@ -214,6 +225,28 @@ class BaseFileHelper return self::$_mimeTypes[$magicFile]; } + private static $_mimeAliases = []; + + /** + * Loads MIME aliases from the specified file. + * @param string $aliasesFile the path (or alias) of the file that contains MIME type aliases. + * If this is not set, the file specified by [[mimeAliasesFile]] will be used. + * @return array the mapping from file extensions to MIME types + * @since 2.0.14 + */ + protected static function loadMimeAliases($aliasesFile) + { + if ($aliasesFile === null) { + $aliasesFile = static::$mimeAliasesFile; + } + $aliasesFile = Yii::getAlias($aliasesFile); + if (!isset(self::$_mimeAliases[$aliasesFile])) { + self::$_mimeAliases[$aliasesFile] = require $aliasesFile; + } + + return self::$_mimeAliases[$aliasesFile]; + } + /** * Copies a whole directory as another one. * The files and sub-directories will also be copied over. diff --git a/framework/helpers/mimeAliases.php b/framework/helpers/mimeAliases.php new file mode 100644 index 0000000..89a9797 --- /dev/null +++ b/framework/helpers/mimeAliases.php @@ -0,0 +1,9 @@ + 'application/xml', +]; diff --git a/tests/framework/validators/FileValidatorTest.php b/tests/framework/validators/FileValidatorTest.php index 58e0d7f..c8e56a9 100644 --- a/tests/framework/validators/FileValidatorTest.php +++ b/tests/framework/validators/FileValidatorTest.php @@ -415,11 +415,7 @@ class FileValidatorTest extends TestCase ['test.png', 'image/*', 'png'], ['test.png', 'IMAGE/*', 'png'], ['test.txt', 'text/*', 'txt'], - // Disabled for PHP 7.2 RC because of regression: - // https://bugs.php.net/bug.php?id=75380 - version_compare(PHP_VERSION, '7.2.0.RC.1', '>=') && version_compare(PHP_VERSION, '7.2.0.RC.6', '<=') - ? null - : ['test.xml', '*/xml', 'xml'], + ['test.xml', '*/xml', 'xml'], ['test.odt', 'application/vnd*', 'odt'], ]); } @@ -445,7 +441,8 @@ class FileValidatorTest extends TestCase { $validator = new FileValidator(['extensions' => (array) $allowedExtensions]); $file = $this->getRealTestFile($fileName); - $this->assertTrue($validator->validate($file)); + $detectedMimeType = FileHelper::getMimeType($file->tempName, null, false); + $this->assertTrue($validator->validate($file), "Mime type detected was \"$detectedMimeType\". Consider adding it to MimeTypeController::\$aliases."); } /**