Skip to content

Commit

Permalink
Merge remote-tracking branch 'Fran6co/cache-buster' into cache-buster
Browse files Browse the repository at this point in the history
Conflicts:
	CHANGELOG-1.1.md
  • Loading branch information
stof committed Sep 14, 2012
2 parents 22b5765 + 503bc9f commit eb0b3b4
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-1.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Fixed the handling of directories in the GlobAsset. #256
* Added Handlebars support
* Added Scssphp-compass support
* Added the CacheBustingWorker

1.1.0-alpha1 (August 28, 2012)
------------------------------
Expand Down
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,36 @@ $js->dump();
$js->dump();
```

Cache Busting
-------------

You can use the CacheBustingWorker to provide unique names.

To strategies are provided: CacheBustingWorker::STRATEGY_CONTENT (content based), CacheBustingWorker::STRATEGY_MODIFICATION (modification time based)

``` php
<?php

use Assetic\Factory\AssetFactory;
use Assetic\Factory\Worker\CacheBustingWorker;

$factory = new AssetFactory('/path/to/asset/directory/');
$factory->setAssetManager($am);
$factory->setFilterManager($fm);
$factory->setDebug(true);
$factory->addWorker(new CacheBustingWorker(CacheBustingWorker::STRATEGY_CONTENT));

$css = $factory->createAsset(array(
'@reset', // load the asset manager's "reset" asset
'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/"
), array(
'scss', // filter through the filter manager's "scss" filter
'?yui_css', // don't use this filter in debug mode
));

echo $css->dump();
```

Static Assets
-------------

Expand Down
78 changes: 78 additions & 0 deletions src/Assetic/Factory/Worker/CacheBustingWorker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2012 OpenSky Project Inc
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Assetic\Factory\Worker;

use Assetic\Asset\AssetInterface;

/**
* Adds cache busting code
*
* @author Kris Wallsmith <[email protected]>
*/
class CacheBustingWorker implements WorkerInterface
{
const STRATEGY_CONTENT = 1;
const STRATEGY_MODIFICATION = 2;

private $strategy;

public function __construct($strategy = self::STRATEGY_CONTENT)
{
$this->strategy = $strategy;
}

public function process(AssetInterface $asset)
{
$hash = hash_init('sha1');

switch($this->strategy) {
case self::STRATEGY_MODIFICATION:
hash_update($hash, $asset->getLastModified());
break;
case self::STRATEGY_CONTENT:
hash_update($hash, $asset->dump());
break;
}

foreach ($asset as $i => $leaf) {
if ($sourcePath = $leaf->getSourcePath()) {
hash_update($hash, $sourcePath);
} else {
hash_update($hash, $i);
}
}

$hash = substr(hash_final($hash), 0, 7);
$url = $asset->getTargetPath();

$oldExt = pathinfo($url, PATHINFO_EXTENSION);
$newExt = '-'.$hash.'.'.$oldExt;

if (!$oldExt || 0 < preg_match('/'.preg_quote($newExt, '/').'$/', $url)) {
return;
}

$asset->setTargetPath(substr($url, 0, (strlen($oldExt) + 1) * -1).$newExt);
}

public function getStrategy()
{
return $this->strategy;
}

public function setStrategy($strategy)
{
$this->strategy = $strategy;

return $this;
}
}
4 changes: 2 additions & 2 deletions tests/Assetic/Test/Factory/AssetFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ public function testCreateGlobAssetAndLoadFiles()
$assets = $this->factory->createAsset(array('*/Fixtures/*/*'));
$assets->load();

$this->assertEquals(4, count(iterator_to_array($assets)), '->createAsset() adds files');
$this->assertEquals(5, count(iterator_to_array($assets)), '->createAsset() adds files');
}

public function testCreateGlobAssetAndExcludeDirectories()
{
$assets = $this->factory->createAsset(array('*/Fixtures/*', '*/Fixtures/*/*'));
$assets->load();

$this->assertEquals(4, count(iterator_to_array($assets)), '->createAsset() excludes directories and add files');
$this->assertEquals(5, count(iterator_to_array($assets)), '->createAsset() excludes directories and add files');
}

public function testCreateAssetCollection()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public function testFollowSymlinks()
++$count;
}

$this->assertEquals(6, $count);
$this->assertEquals(7, $count);
}

public function tearDown()
Expand Down
1 change: 1 addition & 0 deletions tests/Assetic/Test/Factory/Resource/Fixtures/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
body{color:#222;background:#fff;}
76 changes: 76 additions & 0 deletions tests/Assetic/Test/Factory/Worker/CacheBustingWorkerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2012 OpenSky Project Inc
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Assetic\Test\Factory\Worker;

use Assetic\Factory\AssetFactory;
use Assetic\Factory\Worker\CacheBustingWorker;

class CacheBustingWorkerTest extends \PHPUnit_Framework_TestCase
{
private $worker;
private $factory;

protected function setUp()
{
$am = $this->getMock('Assetic\\AssetManager');
$fm = $this->getMock('Assetic\\FilterManager');

$this->worker = new CacheBustingWorker();

$this->factory = new AssetFactory(__DIR__ . '/..');
$this->factory->setAssetManager($am);
$this->factory->setFilterManager($fm);
$this->factory->addWorker($this->worker);
}


public function testGenerateUniqueAssetNameByContent()
{
$this->worker->setStrategy(CacheBustingWorker::STRATEGY_CONTENT);

$filename = 'Resource/Fixtures/css/style.css';
$filepath = __DIR__ . '/../' . $filename;

$originalContent = file_get_contents($filepath);

file_put_contents($filepath, 'body{color:#444;background:#eee;}');
$asset = $this->factory->createAsset(array($filename));
$targetPath1 = $asset->getTargetPath();

file_put_contents($filepath, $originalContent);
$asset = $this->factory->createAsset(array($filename));
$targetPath2 = $asset->getTargetPath();

$this->assertNotEquals($targetPath2, $targetPath1);
}

public function testGenerateUniqueAssetNameByModificationTime()
{
$this->worker->setStrategy(CacheBustingWorker::STRATEGY_MODIFICATION);

$filename = 'Resource/Fixtures/css/style.css';
$filepath = __DIR__ . '/../' . $filename;

$asset = $this->factory->createAsset(array($filename));
$this->factory->addWorker(new CacheBustingWorker('modification'));
$targetPath1 = $asset->getTargetPath();

sleep(1);
touch($filepath);
clearstatcache();

$asset = $this->factory->createAsset(array($filename));
$targetPath2 = $asset->getTargetPath();

$this->assertNotEquals($targetPath2, $targetPath1);
}
}

0 comments on commit eb0b3b4

Please sign in to comment.