From d84898a73d1073f7eb63e85f9346a52503f2bce5 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 24 May 2014 18:39:22 +0400 Subject: [PATCH] Fixes #2898: `yii\console\controllers\AssetController` is now using hashes instead of timestamps --- docs/guide/output-assets.md | 8 ++--- framework/CHANGELOG.md | 1 + framework/UPGRADE.md | 2 ++ .../console/controllers/AssetController.php | 31 +++++++++---------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/docs/guide/output-assets.md b/docs/guide/output-assets.md index 298655c86d..483147a840 100644 --- a/docs/guide/output-assets.md +++ b/docs/guide/output-assets.md @@ -227,8 +227,8 @@ return [ 'app\config\AllAsset' => [ 'basePath' => 'path/to/web', 'baseUrl' => '', - 'js' => 'js/all-{ts}.js', - 'css' => 'css/all-{ts}.css', + 'js' => 'js/all-{hash}.js', + 'css' => 'css/all-{hash}.css', ], ], // Asset manager configuration: @@ -246,8 +246,8 @@ everything to `path/to/web` that can be accessed like `http://example.com/` i.e. > Note: in the console environment some path aliases like '@webroot' and '@web' may not exist, so corresponding paths inside the configuration should be specified directly. -JavaScript files are combined, compressed and written to `js/all-{ts}.js` where {ts} is replaced with current UNIX -timestamp. +JavaScript files are combined, compressed and written to `js/all-{hash}.js` where {hash} is replaced with the hash of +the resulting file. `jsCompressor` and `cssCompressor` are console commands or PHP callbacks, which should perform JavaScript and CSS files compression correspondingly. You should adjust these values according to your environment. diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 60de81d72d..a89d1d85dc 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -67,6 +67,7 @@ Yii Framework 2 Change Log - Enh: Added support for using path alias with `FileDependency::fileName` (qiangxue) - Enh: Added param `hideOnSinglePage` to `yii\widgets\LinkPager` (arturf) - Enh: Added support for array attributes in `in` validator (creocoder) +- Chg #2898: `yii\console\controllers\AssetController` is now using hashes instead of timestamps (samdark) - Chg #2913: RBAC `DbManager` is now initialized via migration (samdark) - Chg #3036: Upgraded Twitter Bootstrap to 3.1.x (qiangxue) - Chg #3175: InvalidCallException, InvalidParamException, UnknownMethodException are now extended from SPL BadMethodCallException (samdark) diff --git a/framework/UPGRADE.md b/framework/UPGRADE.md index 110dff5ede..a437c013cb 100644 --- a/framework/UPGRADE.md +++ b/framework/UPGRADE.md @@ -42,3 +42,5 @@ Upgrade from Yii 2.0 Beta to return cell values (via `yii\grid\DataColumn::value`), you may need to adjust the signature of the callable to be `function ($model, $key, $index, $widget)`. The `$key` parameter was newly added in this release. + +* `yii\console\controllers\AssetController` is now using hashes instead of timestamps. Replace all `{ts}` with `{hash}`. \ No newline at end of file diff --git a/framework/console/controllers/AssetController.php b/framework/console/controllers/AssetController.php index 7e016cf78e..fc493c285f 100644 --- a/framework/console/controllers/AssetController.php +++ b/framework/console/controllers/AssetController.php @@ -10,6 +10,7 @@ namespace yii\console\controllers; use Yii; use yii\console\Exception; use yii\console\Controller; +use yii\helpers\StringHelper; use yii\helpers\VarDumper; /** @@ -52,14 +53,13 @@ class AssetController extends Controller * * ~~~ * 'app\config\AllAsset' => [ - * 'js' => 'js/all-{ts}.js', - * 'css' => 'css/all-{ts}.css', + * 'js' => 'js/all-{hash}.js', + * 'css' => 'css/all-{hash}.css', * 'depends' => [ ... ], * ] * ~~~ * - * File names can contain placeholder "{ts}", which will be filled by current timestamp, while - * file creation. + * File names can contain placeholder "{hash}", which will be filled by the hash of the resulting file. */ public $targets = []; /** @@ -138,14 +138,13 @@ class AssetController extends Controller $this->loadConfiguration($configFile); $bundles = $this->loadBundles($this->bundles); $targets = $this->loadTargets($this->targets, $bundles); - $timestamp = time(); foreach ($targets as $name => $target) { echo "Creating output bundle '{$name}':\n"; if (!empty($target->js)) { - $this->buildTarget($target, 'js', $bundles, $timestamp); + $this->buildTarget($target, 'js', $bundles); } if (!empty($target->css)) { - $this->buildTarget($target, 'css', $bundles, $timestamp); + $this->buildTarget($target, 'css', $bundles); } echo "\n"; } @@ -282,14 +281,11 @@ class AssetController extends Controller * @param \yii\web\AssetBundle $target output asset bundle * @param string $type either 'js' or 'css'. * @param \yii\web\AssetBundle[] $bundles source asset bundles. - * @param integer $timestamp current timestamp. * @throws Exception on failure. */ - protected function buildTarget($target, $type, $bundles, $timestamp) + protected function buildTarget($target, $type, $bundles) { - $outputFile = strtr($target->$type, [ - '{ts}' => $timestamp, - ]); + $tempFile = strtr($target->$type, ['{hash}' => 'temp']); $inputFiles = []; foreach ($target->depends as $name) { @@ -302,10 +298,13 @@ class AssetController extends Controller } } if ($type === 'js') { - $this->compressJsFiles($inputFiles, $target->basePath . '/' . $outputFile); + $this->compressJsFiles($inputFiles, $target->basePath . '/' . $tempFile); } else { - $this->compressCssFiles($inputFiles, $target->basePath . '/' . $outputFile); + $this->compressCssFiles($inputFiles, $target->basePath . '/' . $tempFile); } + + $outputFile = strtr($target->$type, ['{hash}' => md5_file($tempFile)]); + rename($tempFile, $outputFile); $target->$type = [$outputFile]; } @@ -599,8 +598,8 @@ return [ 'app\assets\AllAsset' => [ 'basePath' => 'path/to/web', 'baseUrl' => '', - 'js' => 'js/all-{ts}.js', - 'css' => 'css/all-{ts}.css', + 'js' => 'js/all-{hash}.js', + 'css' => 'css/all-{hash}.css', ], ], // Asset manager configuration: