-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
alexandresalome
committed
Sep 22, 2013
0 parents
commit b9a29b3
Showing
14 changed files
with
749 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/vendor/ | ||
/composer.lock | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
language: php | ||
before_script: | ||
- composer install | ||
php: | ||
- 5.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace Alex\AsseticExtraBundle; | ||
|
||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
class AlexAsseticExtraBundle extends Bundle | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
|
||
namespace Alex\AsseticExtraBundle\Assetic\Filter; | ||
|
||
use Alex\AsseticExtraBundle\Assetic\Util\AssetDirectory; | ||
use Alex\AsseticExtraBundle\Assetic\Util\PathUtils; | ||
use Assetic\Asset\AssetInterface; | ||
use Assetic\Filter\BaseCssFilter; | ||
|
||
/** | ||
* Parses URLs in a CSS and move all assets to a folder, | ||
* changing location of them in CSS. | ||
* | ||
* @author Alexandre Salomé <alexandre.salome@gmail.com> | ||
*/ | ||
class AssetDirectoryFilter extends BaseCssFilter | ||
{ | ||
/** | ||
* @var AssetDirectory | ||
*/ | ||
protected $directory; | ||
|
||
/** | ||
* @param AssetDirectory $directory directory where to store assets | ||
*/ | ||
public function __construct(AssetDirectory $directory) | ||
{ | ||
$this->directory = $directory; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function filterLoad(AssetInterface $asset) | ||
{ | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function filterDump(AssetInterface $asset) | ||
{ | ||
$directory = $this->directory; | ||
|
||
if (null === $asset->getSourcePath() || null === $asset->getTargetPath()) { | ||
return; | ||
} | ||
|
||
$content = $this->filterReferences($asset->getContent(), function ($matches) use ($asset, $directory) { | ||
$url = $matches['url']; | ||
|
||
if (false !== strpos($url, '://')) { | ||
return $matches[0]; | ||
} | ||
|
||
$file = PathUtils::resolveUrl($asset, $url); | ||
$target = $this->directory->add($file); | ||
|
||
$path = PathUtils::resolveRelative($target, $asset->getTargetPath()).basename($file); | ||
|
||
return str_replace($matches['url'], $path, $matches[0]); | ||
}); | ||
|
||
$asset->setContent($content); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
<?php | ||
|
||
namespace Alex\AsseticExtraBundle\Assetic\Util; | ||
|
||
use Assetic\Cache\CacheInterface; | ||
|
||
/** | ||
* Class to interact with a folder containing images. | ||
* | ||
* @author Alexandre Salomé <alexandre.salome@gmail.com> | ||
*/ | ||
class AssetDirectory | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected $directory; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $target; | ||
|
||
/** | ||
* @var CacheInterface | ||
*/ | ||
protected $cache; | ||
|
||
/** | ||
* Constructs a new asset directory | ||
* | ||
* @param string $directory path to the directory of assets | ||
* @param CacheInterface $cache a cache to use, to avoid copying the same file | ||
*/ | ||
public function __construct($directory, $target = null, CacheInterface $cache = null) | ||
{ | ||
$this->directory = $directory; | ||
$this->target = $target; | ||
$this->cache = $cache; | ||
} | ||
|
||
/** | ||
* Copy a file to the directory. | ||
* | ||
* @param string $file fullpath of file to add | ||
* @param boolean $force ignore cache and add file to directory | ||
* | ||
* @throws InvalidArgumentException file does not exist | ||
* @throws RuntimeException filesystem errors | ||
* | ||
* @return string target image path | ||
*/ | ||
public function add($file, $force = false) | ||
{ | ||
if (!file_exists($file)) { | ||
throw new \InvalidArgumentException(sprintf('File "%s" does not exist.', $file)); | ||
} | ||
|
||
if (false === $force && null !== $path = $this->getCache($file)) { | ||
return null === $this->target ? $path : $this->target.'/'.$path; | ||
} | ||
|
||
$name = $this->findAvailableName($file); | ||
|
||
if (null !== $this->cache) { | ||
$this->cache->set(md5($file), serialize(array(filemtime($file), $name))); | ||
} | ||
|
||
if (!is_dir($dir = dirname($target = $this->directory.'/'.$name))) { | ||
mkdir($dir, 0777, true); | ||
} | ||
|
||
if (false === @copy($file, $target)) { | ||
throw new \RuntimeException(sprintf('Error while copying "%s" to "%s".', $file, $target)); | ||
} | ||
|
||
return null === $this->target ? $name : $this->target.'/'.$name; | ||
} | ||
|
||
/** | ||
* Returns directory. | ||
* | ||
* @return string | ||
*/ | ||
public function getDirectory() | ||
{ | ||
return $this->directory; | ||
} | ||
|
||
/** | ||
* Returns target. | ||
* | ||
* @return string | ||
*/ | ||
public function getTarget() | ||
{ | ||
return $this->target; | ||
} | ||
|
||
/** | ||
* Changes target value. | ||
* | ||
* @param string $target a target path | ||
* | ||
* @return AssetDirectory fluid interface | ||
*/ | ||
public function setTarget($target) | ||
{ | ||
$this->target = $target; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Searches a fresh cached file for the given file. | ||
* | ||
* @throws RuntimeException filesystem errors | ||
*/ | ||
private function getCache($file) | ||
{ | ||
if (null === $this->cache) { | ||
return null; | ||
} | ||
|
||
$key = md5($file); | ||
|
||
// File already present | ||
if ($this->cache->has($key)) { | ||
list($mtime, $path) = unserialize($this->cache->get($key)); | ||
|
||
if ($mtime === filemtime($file)) { | ||
return $path; | ||
} | ||
|
||
$delete = $this->directory.'/'.$path; | ||
if (file_exists($delete) && false === @unlink($delete)) { | ||
throw new \RuntimeException('Unable to remove file '.$delete); | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Finds a name not used, incrementing if file already | ||
* exists in storage : foo.png, foo_1.png, foo_2.png... | ||
* | ||
* @return string a relative path | ||
*/ | ||
private function findAvailableName($file) | ||
{ | ||
$name = basename($file); | ||
|
||
if (!file_exists($this->directory.'/'.$name)) { | ||
return $name; | ||
} | ||
|
||
$dotPos = strrpos($name, '.'); | ||
$prefix = substr($name, 0, $dotPos); | ||
$suffix = substr($name, $dotPos); | ||
|
||
$count = 1; | ||
do { | ||
$name = $prefix.'_'.$count.$suffix; | ||
$count++; | ||
} while (file_exists($this->directory.'/'.$name)); | ||
|
||
return $name; | ||
} | ||
} |
Oops, something went wrong.