1<?php 2 3/* 4 * This file is part of the Assetic package, an OpenSky project. 5 * 6 * (c) 2010-2014 OpenSky Project Inc 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Assetic\Factory\Worker; 13 14use Assetic\Asset\AssetCollectionInterface; 15use Assetic\Asset\AssetInterface; 16use Assetic\Factory\AssetFactory; 17 18/** 19 * Adds cache busting code 20 * 21 * @author Kris Wallsmith <kris.wallsmith@gmail.com> 22 */ 23class CacheBustingWorker implements WorkerInterface 24{ 25 private $separator; 26 27 public function __construct($separator = '-') 28 { 29 $this->separator = $separator; 30 } 31 32 public function process(AssetInterface $asset, AssetFactory $factory) 33 { 34 if (!$path = $asset->getTargetPath()) { 35 // no path to work with 36 return; 37 } 38 39 if (!$search = pathinfo($path, PATHINFO_EXTENSION)) { 40 // nothing to replace 41 return; 42 } 43 44 $replace = $this->separator.$this->getHash($asset, $factory).'.'.$search; 45 if (preg_match('/'.preg_quote($replace, '/').'$/', $path)) { 46 // already replaced 47 return; 48 } 49 50 $asset->setTargetPath( 51 preg_replace('/\.'.preg_quote($search, '/').'$/', $replace, $path) 52 ); 53 } 54 55 protected function getHash(AssetInterface $asset, AssetFactory $factory) 56 { 57 $hash = hash_init('sha1'); 58 59 hash_update($hash, $factory->getLastModified($asset)); 60 61 if ($asset instanceof AssetCollectionInterface) { 62 foreach ($asset as $i => $leaf) { 63 $sourcePath = $leaf->getSourcePath(); 64 hash_update($hash, $sourcePath ?: $i); 65 } 66 } 67 68 return substr(hash_final($hash), 0, 7); 69 } 70} 71