Initial commit of Markdown Resume

This includes several vendor libraries: Assetic, LessPHP, Mustache,
SmartyPants, Markdown
This commit is contained in:
Craig Davis
2012-03-04 10:41:18 -06:00
commit f4c52ac4c9
95 changed files with 17961 additions and 0 deletions

386
vendor/Assetic/Factory/AssetFactory.php vendored Executable file
View File

@@ -0,0 +1,386 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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;
use Assetic\Asset\AssetCollection;
use Assetic\Asset\AssetCollectionInterface;
use Assetic\Asset\AssetInterface;
use Assetic\Asset\AssetReference;
use Assetic\Asset\FileAsset;
use Assetic\Asset\GlobAsset;
use Assetic\Asset\HttpAsset;
use Assetic\AssetManager;
use Assetic\Factory\Worker\WorkerInterface;
use Assetic\FilterManager;
/**
* The asset factory creates asset objects.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class AssetFactory
{
private $root;
private $debug;
private $output;
private $workers;
private $am;
private $fm;
/**
* Constructor.
*
* @param string $root The default root directory
* @param string $output The default output string
* @param Boolean $debug Filters prefixed with a "?" will be omitted in debug mode
*/
public function __construct($root, $debug = false)
{
$this->root = rtrim($root, '/');
$this->debug = $debug;
$this->output = 'assetic/*';
$this->workers = array();
}
/**
* Sets debug mode for the current factory.
*
* @param Boolean $debug Debug mode
*/
public function setDebug($debug)
{
$this->debug = $debug;
}
/**
* Checks if the factory is in debug mode.
*
* @return Boolean Debug mode
*/
public function isDebug()
{
return $this->debug;
}
/**
* Sets the default output string.
*
* @param string $output The default output string
*/
public function setDefaultOutput($output)
{
$this->output = $output;
}
/**
* Adds a factory worker.
*
* @param WorkerInterface $worker A worker
*/
public function addWorker(WorkerInterface $worker)
{
$this->workers[] = $worker;
}
/**
* Returns the current asset manager.
*
* @return AssetManager|null The asset manager
*/
public function getAssetManager()
{
return $this->am;
}
/**
* Sets the asset manager to use when creating asset references.
*
* @param AssetManager $am The asset manager
*/
public function setAssetManager(AssetManager $am)
{
$this->am = $am;
}
/**
* Returns the current filter manager.
*
* @return FilterManager|null The filter manager
*/
public function getFilterManager()
{
return $this->fm;
}
/**
* Sets the filter manager to use when adding filters.
*
* @param FilterManager $fm The filter manager
*/
public function setFilterManager(FilterManager $fm)
{
$this->fm = $fm;
}
/**
* Creates a new asset.
*
* Prefixing a filter name with a question mark will cause it to be
* omitted when the factory is in debug mode.
*
* Available options:
*
* * output: An output string
* * name: An asset name for interpolation in output patterns
* * debug: Forces debug mode on or off for this asset
* * root: An array or string of more root directories
*
* @param array|string $inputs An array of input strings
* @param array|string $filters An array of filter names
* @param array $options An array of options
*
* @return AssetCollection An asset collection
*/
public function createAsset($inputs = array(), $filters = array(), array $options = array())
{
if (!is_array($inputs)) {
$inputs = array($inputs);
}
if (!is_array($filters)) {
$filters = array($filters);
}
if (!isset($options['output'])) {
$options['output'] = $this->output;
}
if (!isset($options['vars'])) {
$options['vars'] = array();
}
if (!isset($options['debug'])) {
$options['debug'] = $this->debug;
}
if (!isset($options['root'])) {
$options['root'] = array($this->root);
} else {
if (!is_array($options['root'])) {
$options['root'] = array($options['root']);
}
$options['root'][] = $this->root;
}
if (!isset($options['name'])) {
$options['name'] = $this->generateAssetName($inputs, $filters, $options);
}
$asset = $this->createAssetCollection(array(), $options);
$extensions = array();
// inner assets
foreach ($inputs as $input) {
if (is_array($input)) {
// nested formula
$asset->add(call_user_func_array(array($this, 'createAsset'), $input));
} else {
$asset->add($this->parseInput($input, $options));
$extensions[pathinfo($input, PATHINFO_EXTENSION)] = true;
}
}
// filters
foreach ($filters as $filter) {
if ('?' != $filter[0]) {
$asset->ensureFilter($this->getFilter($filter));
} elseif (!$options['debug']) {
$asset->ensureFilter($this->getFilter(substr($filter, 1)));
}
}
// append variables
if (!empty($options['vars'])) {
$toAdd = array();
foreach ($options['vars'] as $var) {
if (false !== strpos($options['output'], '{'.$var.'}')) {
continue;
}
$toAdd[] = '{'.$var.'}';
}
if ($toAdd) {
$options['output'] = str_replace('*', '*.'.implode('.', $toAdd), $options['output']);
}
}
// append consensus extension if missing
if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) {
$options['output'] .= '.'.$extension;
}
// output --> target url
$asset->setTargetPath(str_replace('*', $options['name'], $options['output']));
// apply workers and return
return $this->applyWorkers($asset);
}
public function generateAssetName($inputs, $filters, $options = array())
{
foreach (array_diff(array_keys($options), array('output', 'debug', 'root')) as $key) {
unset($options[$key]);
}
ksort($options);
return substr(sha1(serialize($inputs).serialize($filters).serialize($options)), 0, 7);
}
/**
* Parses an input string string into an asset.
*
* The input string can be one of the following:
*
* * A reference: If the string starts with an "at" sign it will be interpreted as a reference to an asset in the asset manager
* * An absolute URL: If the string contains "://" or starts with "//" it will be interpreted as an HTTP asset
* * A glob: If the string contains a "*" it will be interpreted as a glob
* * A path: Otherwise the string is interpreted as a filesystem path
*
* Both globs and paths will be absolutized using the current root directory.
*
* @param string $input An input string
* @param array $options An array of options
*
* @return AssetInterface An asset
*/
protected function parseInput($input, array $options = array())
{
if ('@' == $input[0]) {
return $this->createAssetReference(substr($input, 1));
}
if (false !== strpos($input, '://') || 0 === strpos($input, '//')) {
return $this->createHttpAsset($input, $options['vars']);
}
if (self::isAbsolutePath($input)) {
if ($root = self::findRootDir($input, $options['root'])) {
$path = ltrim(substr($input, strlen($root)), '/');
} else {
$path = null;
}
} else {
$root = $this->root;
$path = $input;
$input = $this->root.'/'.$path;
}
if (false !== strpos($input, '*')) {
return $this->createGlobAsset($input, $root, $options['vars']);
} else {
return $this->createFileAsset($input, $root, $path, $options['vars']);
}
}
protected function createAssetCollection(array $assets = array(), array $options = array())
{
return new AssetCollection($assets, array(), null, isset($options['vars']) ? $options['vars'] : array());
}
protected function createAssetReference($name)
{
if (!$this->am) {
throw new \LogicException('There is no asset manager.');
}
return new AssetReference($this->am, $name);
}
protected function createHttpAsset($sourceUrl, $vars)
{
return new HttpAsset($sourceUrl, array(), false, $vars);
}
protected function createGlobAsset($glob, $root = null, $vars)
{
return new GlobAsset($glob, array(), $root, $vars);
}
protected function createFileAsset($source, $root = null, $path = null, $vars)
{
return new FileAsset($source, array(), $root, $path, $vars);
}
protected function getFilter($name)
{
if (!$this->fm) {
throw new \LogicException('There is no filter manager.');
}
return $this->fm->get($name);
}
/**
* Filters an asset collection through the factory workers.
*
* Each leaf asset will be processed first, followed by the asset
* collection itself.
*
* @param AssetCollectionInterface $asset An asset collection
*/
private function applyWorkers(AssetCollectionInterface $asset)
{
foreach ($asset as $leaf) {
foreach ($this->workers as $worker) {
$retval = $worker->process($leaf);
if ($retval instanceof AssetInterface && $leaf !== $retval) {
$asset->replaceLeaf($leaf, $retval);
}
}
}
foreach ($this->workers as $worker) {
$retval = $worker->process($asset);
if ($retval instanceof AssetInterface) {
$asset = $retval;
}
}
return $asset instanceof AssetCollectionInterface ? $asset : $this->createAssetCollection(array($asset));
}
static private function isAbsolutePath($path)
{
return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2]));
}
/**
* Loops through the root directories and returns the first match.
*
* @param string $path An absolute path
* @param array $roots An array of root directories
*
* @return string|null The matching root directory, if found
*/
static private function findRootDir($path, array $roots)
{
foreach ($roots as $root) {
if (0 === strpos($path, $root)) {
return $root;
}
}
}
}

204
vendor/Assetic/Factory/LazyAssetManager.php vendored Executable file
View File

@@ -0,0 +1,204 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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;
use Assetic\AssetManager;
use Assetic\Factory\Loader\FormulaLoaderInterface;
use Assetic\Factory\Resource\ResourceInterface;
/**
* A lazy asset manager is a composition of a factory and many formula loaders.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class LazyAssetManager extends AssetManager
{
private $factory;
private $loaders;
private $resources;
private $formulae;
private $loaded;
private $loading;
/**
* Constructor.
*
* @param AssetFactory $factory The asset factory
* @param array $loaders An array of loaders indexed by alias
*/
public function __construct(AssetFactory $factory, $loaders = array())
{
$this->factory = $factory;
$this->loaders = array();
$this->resources = array();
$this->formulae = array();
$this->loaded = false;
$this->loading = false;
foreach ($loaders as $alias => $loader) {
$this->setLoader($alias, $loader);
}
}
/**
* Adds a loader to the asset manager.
*
* @param string $alias An alias for the loader
* @param FormulaLoaderInterface $loader A loader
*/
public function setLoader($alias, FormulaLoaderInterface $loader)
{
$this->loaders[$alias] = $loader;
$this->loaded = false;
}
/**
* Adds a resource to the asset manager.
*
* @param ResourceInterface $resource A resource
* @param string $loader The loader alias for this resource
*/
public function addResource(ResourceInterface $resource, $loader)
{
$this->resources[$loader][] = $resource;
$this->loaded = false;
}
/**
* Returns an array of resources.
*
* @return array An array of resources
*/
public function getResources()
{
$resources = array();
foreach ($this->resources as $r) {
$resources = array_merge($resources, $r);
}
return $resources;
}
/**
* Checks for an asset formula.
*
* @param string $name An asset name
*
* @return Boolean If there is a formula
*/
public function hasFormula($name)
{
if (!$this->loaded) {
$this->load();
}
return isset($this->formulae[$name]);
}
/**
* Returns an asset's formula.
*
* @param string $name An asset name
*
* @return array The formula
*
* @throws InvalidArgumentException If there is no formula by that name
*/
public function getFormula($name)
{
if (!$this->loaded) {
$this->load();
}
if (!isset($this->formulae[$name])) {
throw new \InvalidArgumentException(sprintf('There is no "%s" formula.', $name));
}
return $this->formulae[$name];
}
/**
* Sets a formula on the asset manager.
*
* @param string $name An asset name
* @param array $formula A formula
*/
public function setFormula($name, array $formula)
{
$this->formulae[$name] = $formula;
}
/**
* Loads formulae from resources.
*
* @throws LogicException If a resource has been added to an invalid loader
*/
public function load()
{
if ($this->loading) {
return;
}
if ($diff = array_diff(array_keys($this->resources), array_keys($this->loaders))) {
throw new \LogicException('The following loader(s) are not registered: '.implode(', ', $diff));
}
$this->loading = true;
foreach ($this->resources as $loader => $resources) {
foreach ($resources as $resource) {
$this->formulae = array_replace($this->formulae, $this->loaders[$loader]->load($resource));
}
}
$this->loaded = true;
$this->loading = false;
}
public function get($name)
{
if (!$this->loaded) {
$this->load();
}
if (!parent::has($name) && isset($this->formulae[$name])) {
list($inputs, $filters, $options) = $this->formulae[$name];
$options['name'] = $name;
parent::set($name, $this->factory->createAsset($inputs, $filters, $options));
}
return parent::get($name);
}
public function has($name)
{
if (!$this->loaded) {
$this->load();
}
return isset($this->formulae[$name]) || parent::has($name);
}
public function getNames()
{
if (!$this->loaded) {
$this->load();
}
return array_unique(array_merge(parent::getNames(), array_keys($this->formulae)));
}
public function isDebug()
{
return $this->factory->isDebug();
}
}

View File

@@ -0,0 +1,159 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Loader;
use Assetic\Factory\AssetFactory;
use Assetic\Factory\Resource\ResourceInterface;
/**
* Loads asset formulae from PHP files.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
abstract class BasePhpFormulaLoader implements FormulaLoaderInterface
{
protected $factory;
protected $prototypes;
public function __construct(AssetFactory $factory)
{
$this->factory = $factory;
$this->prototypes = array();
foreach ($this->registerPrototypes() as $prototype => $options) {
$this->addPrototype($prototype, $options);
}
}
public function addPrototype($prototype, array $options = array())
{
$tokens = token_get_all('<?php '.$prototype);
array_shift($tokens);
$this->prototypes[$prototype] = array($tokens, $options);
}
public function load(ResourceInterface $resource)
{
if (!$nbProtos = count($this->prototypes)) {
throw new \LogicException('There are no prototypes registered.');
}
$buffers = array_fill(0, $nbProtos, '');
$bufferLevels = array_fill(0, $nbProtos, 0);
$buffersInWildcard = array();
$tokens = token_get_all($resource->getContent());
$calls = array();
while ($token = array_shift($tokens)) {
$current = self::tokenToString($token);
// loop through each prototype (by reference)
foreach (array_keys($this->prototypes) as $i) {
$prototype =& $this->prototypes[$i][0];
$options = $this->prototypes[$i][1];
$buffer =& $buffers[$i];
$level =& $bufferLevels[$i];
if (isset($buffersInWildcard[$i])) {
switch ($current) {
case '(': ++$level; break;
case ')': --$level; break;
}
$buffer .= $current;
if (!$level) {
$calls[] = array($buffer.';', $options);
$buffer = '';
unset($buffersInWildcard[$i]);
}
} elseif ($current == self::tokenToString(current($prototype))) {
$buffer .= $current;
if ('*' == self::tokenToString(next($prototype))) {
$buffersInWildcard[$i] = true;
++$level;
}
} else {
reset($prototype);
unset($buffersInWildcard[$i]);
$buffer = '';
}
}
}
$formulae = array();
foreach ($calls as $call) {
$formulae += call_user_func_array(array($this, 'processCall'), $call);
}
return $formulae;
}
private function processCall($call, array $protoOptions = array())
{
$tmp = tempnam(sys_get_temp_dir(), 'assetic');
file_put_contents($tmp, implode("\n", array(
'<?php',
$this->registerSetupCode(),
$call,
'echo serialize($_call);',
)));
$args = unserialize(shell_exec('php '.escapeshellarg($tmp)));
unlink($tmp);
$inputs = isset($args[0]) ? self::argumentToArray($args[0]) : array();
$filters = isset($args[1]) ? self::argumentToArray($args[1]) : array();
$options = isset($args[2]) ? $args[2] : array();
if (!isset($options['debug'])) {
$options['debug'] = $this->factory->isDebug();
}
if (!is_array($options)) {
throw new \RuntimeException('The third argument must be omitted, null or an array.');
}
// apply the prototype options
$options += $protoOptions;
if (!isset($options['name'])) {
$options['name'] = $this->factory->generateAssetName($inputs, $filters, $options);
}
return array($options['name'] => array($inputs, $filters, $options));
}
/**
* Returns an array of prototypical calls and options.
*
* @return array Prototypes and options
*/
abstract protected function registerPrototypes();
/**
* Returns setup code for the reflection scriptlet.
*
* @return string Some PHP setup code
*/
abstract protected function registerSetupCode();
static protected function tokenToString($token)
{
return is_array($token) ? $token[1] : $token;
}
static protected function argumentToArray($argument)
{
return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument)));
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Loader;
use Assetic\Cache\ConfigCache;
use Assetic\Factory\Resource\IteratorResourceInterface;
use Assetic\Factory\Resource\ResourceInterface;
/**
* Adds a caching layer to a loader.
*
* A cached formula loader is a composition of a formula loader and a cache.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class CachedFormulaLoader implements FormulaLoaderInterface
{
private $loader;
private $configCache;
private $debug;
/**
* Constructor.
*
* When the loader is in debug mode it will ensure the cached formulae
* are fresh before returning them.
*
* @param FormulaLoaderInterface $loader A formula loader
* @param ConfigCache $configCache A config cache
* @param Boolean $debug The debug mode
*/
public function __construct(FormulaLoaderInterface $loader, ConfigCache $configCache, $debug = false)
{
$this->loader = $loader;
$this->configCache = $configCache;
$this->debug = $debug;
}
public function load(ResourceInterface $resources)
{
if (!$resources instanceof IteratorResourceInterface) {
$resources = array($resources);
}
$formulae = array();
foreach ($resources as $resource) {
$id = (string) $resource;
if (!$this->configCache->has($id) || ($this->debug && !$resource->isFresh($this->configCache->getTimestamp($id)))) {
$formulae += $this->loader->load($resource);
$this->configCache->set($id, $formulae);
} else {
$formulae += $this->configCache->get($id);
}
}
return $formulae;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Loader;
use Assetic\Factory\Resource\ResourceInterface;
/**
* Loads formulae.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
interface FormulaLoaderInterface
{
/**
* Loads formulae from a resource.
*
* Formulae should be loaded the same regardless of the current debug
* mode. Debug considerations should happen downstream.
*
* @param ResourceInterface $resource A resource
*
* @return array An array of formulae
*/
function load(ResourceInterface $resource);
}

View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Loader;
/**
* Loads asset formulae from PHP files.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class FunctionCallsFormulaLoader extends BasePhpFormulaLoader
{
protected function registerPrototypes()
{
return array(
'assetic_javascripts(*)' => array('output' => 'js/*.js'),
'assetic_stylesheets(*)' => array('output' => 'css/*.css'),
'assetic_image(*)' => array('output' => 'images/*'),
);
}
protected function registerSetupCode()
{
return <<<'EOF'
function assetic_javascripts()
{
global $_call;
$_call = func_get_args();
}
function assetic_stylesheets()
{
global $_call;
$_call = func_get_args();
}
function assetic_image()
{
global $_call;
$_call = func_get_args();
}
EOF;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Resource;
/**
* Coalesces multiple directories together into one merged resource.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class CoalescingDirectoryResource implements IteratorResourceInterface
{
private $directories;
public function __construct($directories)
{
$this->directories = array();
foreach ($directories as $directory) {
$this->addDirectory($directory);
}
}
public function addDirectory(IteratorResourceInterface $directory)
{
$this->directories[] = $directory;
}
public function isFresh($timestamp)
{
foreach ($this->getFileResources() as $file) {
if (!$file->isFresh($timestamp)) {
return false;
}
}
return true;
}
public function getContent()
{
$parts = array();
foreach ($this->getFileResources() as $file) {
$parts[] = $file->getContent();
}
return implode("\n", $parts);
}
/**
* Returns a string to uniquely identify the current resource.
*
* @return string An identifying string
*/
public function __toString()
{
$parts = array();
foreach ($this->directories as $directory) {
$parts[] = (string) $directory;
}
return implode(',', $parts);
}
public function getIterator()
{
return new \ArrayIterator($this->getFileResources());
}
/**
* Returns the relative version of a filename.
*
* @param ResourceInterface $file The file
* @param ResourceInterface $directory The directory
*
* @return string The name to compare with files from other directories
*/
protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory)
{
return substr((string) $file, strlen((string) $directory));
}
/**
* Performs the coalesce.
*
* @return array An array of file resources
*/
private function getFileResources()
{
$paths = array();
foreach ($this->directories as $directory) {
foreach ($directory as $file) {
$relative = $this->getRelativeName($file, $directory);
if (!isset($paths[$relative])) {
$paths[$relative] = $file;
}
}
}
return array_values($paths);
}
}

View File

@@ -0,0 +1,133 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Resource;
/**
* A resource is something formulae can be loaded from.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class DirectoryResource implements IteratorResourceInterface
{
private $path;
private $pattern;
/**
* Constructor.
*
* @param string $path A directory path
* @param string $pattern A filename pattern
*/
public function __construct($path, $pattern = null)
{
if (DIRECTORY_SEPARATOR != substr($path, -1)) {
$path .= DIRECTORY_SEPARATOR;
}
$this->path = $path;
$this->pattern = $pattern;
}
public function isFresh($timestamp)
{
if (!is_dir($this->path) || filemtime($this->path) > $timestamp) {
return false;
}
foreach ($this as $resource) {
if (!$resource->isFresh($timestamp)) {
return false;
}
}
return true;
}
/**
* Returns the combined content of all inner resources.
*/
public function getContent()
{
$content = array();
foreach ($this as $resource) {
$content[] = $resource->getContent();
}
return implode("\n", $content);
}
public function __toString()
{
return $this->path;
}
public function getIterator()
{
return is_dir($this->path)
? new DirectoryResourceIterator($this->getInnerIterator())
: new \EmptyIterator();
}
protected function getInnerIterator()
{
return new DirectoryResourceFilterIterator(new \RecursiveDirectoryIterator($this->path), $this->pattern);
}
}
/**
* An iterator that converts file objects into file resources.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @access private
*/
class DirectoryResourceIterator extends \RecursiveIteratorIterator
{
public function current()
{
return new FileResource(parent::current()->getPathname());
}
}
/**
* Filters files by a basename pattern.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @access private
*/
class DirectoryResourceFilterIterator extends \RecursiveFilterIterator
{
protected $pattern;
public function __construct(\RecursiveDirectoryIterator $iterator, $pattern = null)
{
parent::__construct($iterator);
$this->pattern = $pattern;
}
public function accept()
{
$file = $this->current();
$name = $file->getBasename();
if ($file->isDir()) {
return '.' != $name[0];
} else {
return null === $this->pattern || 0 < preg_match($this->pattern, $name);
}
}
public function getChildren()
{
return new self(new \RecursiveDirectoryIterator($this->current()->getPathname()), $this->pattern);
}
}

View File

@@ -0,0 +1,47 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Resource;
/**
* A resource is something formulae can be loaded from.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
class FileResource implements ResourceInterface
{
private $path;
/**
* Constructor.
*
* @param string $path The path to a file
*/
public function __construct($path)
{
$this->path = $path;
}
public function isFresh($timestamp)
{
return file_exists($this->path) && filemtime($this->path) <= $timestamp;
}
public function getContent()
{
return file_exists($this->path) ? file_get_contents($this->path) : '';
}
public function __toString()
{
return $this->path;
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Resource;
/**
* A resource is something formulae can be loaded from.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
interface IteratorResourceInterface extends ResourceInterface, \IteratorAggregate
{
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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\Resource;
/**
* A resource is something formulae can be loaded from.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
interface ResourceInterface
{
/**
* Checks if a timestamp represents the latest resource.
*
* @param integer $timestamp A UNIX timestamp
*
* @return Boolean True if the timestamp is up to date
*/
function isFresh($timestamp);
/**
* Returns the content of the resource.
*
* @return string The content
*/
function getContent();
/**
* Returns a unique string for the current resource.
*
* @return string A unique string to identity the current resource
*/
function __toString();
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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;
use Assetic\Filter\FilterInterface;
/**
* Applies a filter to an asset based on a source and/or target path match.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @todo A better asset-matcher mechanism
*/
class EnsureFilterWorker implements WorkerInterface
{
const CHECK_SOURCE = 1;
const CHECK_TARGET = 2;
private $pattern;
private $filter;
private $flags;
/**
* Constructor.
*
* @param string $pattern A regex for checking the asset's target URL
* @param FilterInterface $filter A filter to apply if the regex matches
* @param integer $flags Flags for what to check
*/
public function __construct($pattern, FilterInterface $filter, $flags = null)
{
if (null === $flags) {
$flags = self::CHECK_SOURCE | self::CHECK_TARGET;
}
$this->pattern = $pattern;
$this->filter = $filter;
$this->flags = $flags;
}
public function process(AssetInterface $asset)
{
if (
(self::CHECK_SOURCE === (self::CHECK_SOURCE & $this->flags) && preg_match($this->pattern, $asset->getSourcePath()))
||
(self::CHECK_TARGET === (self::CHECK_TARGET & $this->flags) && preg_match($this->pattern, $asset->getTargetPath()))
) {
$asset->ensureFilter($this->filter);
}
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Assetic package, an OpenSky project.
*
* (c) 2010-2011 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;
/**
* Assets are passed through factory workers before leaving the factory.
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
*/
interface WorkerInterface
{
/**
* Processes an asset.
*
* @param AssetInterface $asset An asset
*
* @return AssetInterface|null May optionally return a replacement asset
*/
function process(AssetInterface $asset);
}