Skip to content

Instantly share code, notes, and snippets.

@lyrixx
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lyrixx/069338117ec7d48d6272 to your computer and use it in GitHub Desktop.
Save lyrixx/069338117ec7d48d6272 to your computer and use it in GitHub Desktop.
VersionCalculator
<?php
namespace SensioLabs\Toolkit\Assets;
use Assetic\AssetManager;
use Assetic\Asset\AssetCollection;
use Symfony\Component\Finder\Finder;
class VersionCalculator
{
private $rootDir;
private $assetsFolders;
private $asseticEnabled;
private $am;
private $debug;
private $extensions;
private $ignoredPaths;
public function __construct($rootDir, array $assetsFolders = array(), $asseticEnabled = true, AssetManager $am = null)
{
$this->rootDir = $rootDir;
$this->assetsFolders = $assetsFolders;
$this->asseticEnabled = $asseticEnabled;
$this->am = $am;
// We do no want to use symfony-env and/or symfony-debug
// Because this debug mode, is present only for hard-core debug ;)
$this->debug = '1' === getenv('SLT_AV_DEBUG');
$this->extensions = array(
'js', 'coffee',
'css', 'less',
'ttf', 'woff',
'png', 'jpg',
'ico',
'swf',
);
$this->ignoredPaths = array(
'\/test\/', '\/tests\/',
'\/fixture\/', '\/fixtures\/',
'\/vendor\/', '\/vendors\/',
'\/example\/', '\/examples\/',
'\/sample\/', '\/samples\/',
'\/doc\/', '\/docs\/',
);
}
public function addCustomExtension($extension)
{
if (!isset($extension[0]) || '.' === $extension[0]) {
throw new \InvalidArgumentException('"%s" is not a valid extension', $extension);
}
$this->extensions[] = $extension;
return $this;
}
public function removeExtension($extension)
{
if (!in_array($extension, $this->extensions)) {
return false;
}
$this->extensions = array_filter($this->extensions, function ($v) use ($extension) {
return $v !== $extension;
});
return true;
}
public function addCustomIgnoredPath($path)
{
$this->ignoredPaths[] = $path;
return $this;
}
public function removeIgnoredPath($path)
{
if (!in_array($path, $this->ignoredPaths)) {
return false;
}
$this->ignoredPaths = array_filter($this->ignoredPaths, function ($v) use ($path) {
return $v !== $path;
});
return true;
}
public function computeAssetsVersion()
{
$hashContext = hash_init('sha1');
if ($this->asseticEnabled) {
$this->computeAsseticVersion($hashContext);
}
if ($this->assetsFolders) {
$this->computeStandaloneAssetVersion($hashContext, $this->assetsFolders);
}
// Always prepend a `v` to avoid side effects (string casted to int) with
// this kind of version 811486e356 (=> INF)
return 'v'.substr(hash_final($hashContext), 0, 10);
}
private function computeAsseticVersion($hashContext)
{
$names = $this->am->getNames();
sort($names);
foreach ($names as $name) {
$asset = $this->am->get($name);
if (!$asset instanceof AssetCollection) {
throw new \LogicException(sprintf('This command can not handle asset of type "%s"', get_class($asset)));
}
foreach ($asset as $item) {
$file = sprintf('%s/%s', $item->getSourceRoot(), $item->getSourcePath());
hash_update_file($hashContext, $file);
if ($this->debug) {
echo sprintf("%s: %s\n", $file, md5_file($file));
}
}
}
}
private function computeStandaloneAssetVersion($hashContext, array $folders = array())
{
if (!is_dir($this->rootDir.'/../web/bundles/')) {
throw new \LogicException('You should install asset before running this command (app/console assets:install)');
}
$finder = Finder::create()->useBestAdapter()->sortByName()->files();
foreach ($this->ignoredPaths as $path) {
$finder->notPath($path);
}
foreach ($this->extensions as $extension) {
$finder->name(sprintf('*.%s', $extension));
}
foreach ($folders as $folder) {
if (!is_dir($folder) && !glob($folder)) {
continue;
}
$finder->in($folder);
}
foreach ($finder as $file) {
hash_update_file($hashContext, $file);
if ($this->debug) {
echo sprintf("%s: %s\n", $file, md5_file($file));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment