Introduce deep hashing on asset combiner

Added cms.enableAssetDeepHashing config item, disabled by default
Recompile assets
Refs #2248
Refs https://github.com/octobercms/library/pull/225
This commit is contained in:
Samuel Georges 2016-07-30 15:06:50 +10:00
parent a50d3c1387
commit b08e2c4912
3 changed files with 78 additions and 2 deletions

View File

@ -166,6 +166,20 @@ return [
'enableAssetMinify' => null,
/*
|--------------------------------------------------------------------------
| Check import timestamps when combining assets
|--------------------------------------------------------------------------
|
| If deep hashing is enabled, the combiner cache will be reset when a change
| is detected on imported files, in addition to those referenced directly.
| This will cause slower page performance. If set to null, assets are
| minified, when debug mode (app.debug) is disabled.
|
*/
'enableAssetDeepHashing' => false,
/*
|--------------------------------------------------------------------------
| Public plugins path

File diff suppressed because one or more lines are too long

View File

@ -14,6 +14,7 @@ use Assetic\Asset\FileAsset;
use Assetic\Asset\GlobAsset;
use Assetic\Asset\AssetCache;
use Assetic\Asset\AssetCollection;
use Assetic\Factory\AssetFactory;
use October\Rain\Parse\Assetic\FilesystemCache;
use System\Helpers\Cache as CacheHelper;
use ApplicationException;
@ -75,6 +76,12 @@ class CombineAssets
*/
public $useMinify = false;
/**
* @var bool When true, cache will be busted when an import is modified.
* Enabling this feature will make page loading slower.
*/
public $useDeepHashing = false;
/**
* @var array Cache of registration callbacks.
*/
@ -90,11 +97,16 @@ class CombineAssets
*/
$this->useCache = Config::get('cms.enableAssetCache', false);
$this->useMinify = Config::get('cms.enableAssetMinify', null);
$this->useDeepHashing = Config::get('cms.enableAssetDeepHashing', null);
if ($this->useMinify === null) {
$this->useMinify = !Config::get('app.debug', false);
}
if ($this->useDeepHashing === null) {
$this->useDeepHashing = Config::get('app.debug', false);
}
/*
* Register JavaScript filters
*/
@ -176,6 +188,8 @@ class CombineAssets
$this->localPath = $cacheInfo['path'];
$this->storagePath = storage_path('cms/combiner/assets');
$this->setHashOnCombinerFilters($cacheKey);
$combiner = $this->prepareCombiner($cacheInfo['files']);
$contents = $combiner->dump();
$mime = ($cacheInfo['extension'] == 'css') ? 'text/css' : 'application/javascript';
@ -292,8 +306,11 @@ class CombineAssets
$cacheInfo = $this->useCache ? $this->getCache($cacheKey) : false;
if (!$cacheInfo) {
$this->setHashOnCombinerFilters($cacheKey);
$combiner = $this->prepareCombiner($assets);
$lastMod = $combiner->getLastModified();
$factory = new AssetFactory($this->localPath);
$lastMod = $factory->getLastModified($combiner);
$cacheInfo = [
'version' => $cacheKey.'-'.$lastMod,
@ -354,6 +371,44 @@ class CombineAssets
return $cachedCollection;
}
/**
* Busts the cache based on a different cache key.
* @return void
*/
protected function setHashOnCombinerFilters($hash)
{
$allFilters = call_user_func_array('array_merge', $this->getFilters());
foreach ($allFilters as $filter) {
if (method_exists($filter, 'setHash')) {
$filter->setHash($hash);
}
}
}
/**
* Returns a deep hash on filters that support it.
* @return void
*/
protected function getDeepHashFromAssets($assets)
{
$key = '';
$allFilters = call_user_func_array('array_merge', $this->getFilters());
$assetFiles = array_map(function($file) {
return $this->localPath.'/'.$file;
}, $assets);
foreach ($allFilters as $filter) {
if (method_exists($filter, 'hashFromAssets')) {
$key .= $filter->hashFromAssets($assetFiles, $this->localPath);
}
}
return $key;
}
/**
* Returns the URL used for accessing the combined files.
* @param string $outputFilename A custom file name to use.
@ -663,6 +718,13 @@ class CombineAssets
{
$cacheKey = $this->localPath . implode('|', $assets);
/*
* Deep hashing
*/
if ($this->useDeepHashing) {
$cacheKey .= $this->getDeepHashFromAssets($assets);
}
/*
* Extensibility
*/