Skip to content

Commit ebd6f03

Browse files
committed
Merge pull request #116 from skors/master
support simple concatenation of files like collections
2 parents 7f1c4f3 + 6ab3f2d commit ebd6f03

File tree

7 files changed

+575
-0
lines changed

7 files changed

+575
-0
lines changed

config/module.config.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'AssetManager\Resolver\PathStackResolver' => 'AssetManager\Service\PathStackResolverServiceFactory',
1111
'AssetManager\Resolver\PrioritizedPathsResolver' => 'AssetManager\Service\PrioritizedPathsResolverServiceFactory',
1212
'AssetManager\Resolver\CollectionResolver' => 'AssetManager\Service\CollectionResolverServiceFactory',
13+
'AssetManager\Resolver\ConcatResolver' => 'AssetManager\Service\ConcatResolverServiceFactory',
1314
),
1415

1516
'invokables' => array(
@@ -24,6 +25,7 @@
2425
'asset_manager' => array(
2526
'resolvers' => array(
2627
'AssetManager\Resolver\MapResolver' => 2000,
28+
'AssetManager\Resolver\ConcatResolver' => 1750,
2729
'AssetManager\Resolver\CollectionResolver' => 1500,
2830
'AssetManager\Resolver\PrioritizedPathsResolver' => 1000,
2931
'AssetManager\Resolver\PathStackResolver' => 500,
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
namespace AssetManager\Asset;
4+
5+
use Assetic\Filter\FilterInterface;
6+
use Assetic\Asset\BaseAsset;
7+
use AssetManager\Exception;
8+
9+
/**
10+
* Represents a concatented string asset.
11+
*/
12+
class AggregateAsset extends BaseAsset
13+
{
14+
/**
15+
* @var int Timestamp of last modified date from asset
16+
*/
17+
private $lastModified;
18+
19+
public $mimetype;
20+
21+
/**
22+
* Constructor.
23+
*
24+
* @param array $content The array of assets to be merged
25+
* @param array $filters Filters for the asset
26+
* @param string $sourceRoot The source asset root directory
27+
* @param string $sourcePath The source asset path
28+
*/
29+
public function __construct(array $content = array(), $filters = array(), $sourceRoot = null, $sourcePath = null)
30+
{
31+
parent::__construct($filters, $sourceRoot, $sourcePath);
32+
$this->processContent($content);
33+
}
34+
35+
/**
36+
* load asset
37+
*
38+
* @param FilterInterface $additionalFilter
39+
*/
40+
public function load(FilterInterface $additionalFilter = null)
41+
{
42+
$this->doLoad($this->getContent(), $additionalFilter);
43+
}
44+
45+
/**
46+
* set last modified value of asset
47+
*
48+
* this is useful for cache mechanism detection id file has changed
49+
*
50+
* @param int $lastModified
51+
*/
52+
public function setLastModified($lastModified)
53+
{
54+
$this->lastModified = $lastModified;
55+
}
56+
57+
/**
58+
* get last modified value from asset
59+
*
60+
* @return int|null
61+
*/
62+
public function getLastModified()
63+
{
64+
return $this->lastModified;
65+
}
66+
67+
/**
68+
* Loop through assets and merge content
69+
*
70+
* @param string $content
71+
*
72+
* @throws Exception\RuntimeException
73+
*/
74+
private function processContent($content)
75+
{
76+
$this->mimetype = null;
77+
foreach ($content as $asset) {
78+
if (null === $this->mimetype) {
79+
$this->mimetype = $asset->mimetype;
80+
}
81+
82+
if ($asset->mimetype !== $this->mimetype) {
83+
throw new Exception\RuntimeException(
84+
sprintf(
85+
'Asset "%s" doesn\'t have the expected mime-type "%s".',
86+
$asset->getTargetPath(),
87+
$this->mimetype
88+
)
89+
);
90+
}
91+
92+
$this->setLastModified(
93+
max(
94+
$asset->getLastModified(),
95+
$this->getLastModified()
96+
)
97+
);
98+
$this->setContent(
99+
$this->getContent() . $asset->dump()
100+
);
101+
}
102+
}
103+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<?php
2+
3+
namespace AssetManager\Resolver;
4+
5+
use Traversable;
6+
use Zend\Stdlib\ArrayUtils;
7+
use Assetic\Asset\AssetInterface;
8+
use AssetManager\Asset\AggregateAsset;
9+
use AssetManager\Exception;
10+
use AssetManager\Service\AssetFilterManagerAwareInterface;
11+
use AssetManager\Service\AssetFilterManager;
12+
use AssetManager\Service\MimeResolver;
13+
14+
/**
15+
* This resolver allows the resolving of concatenated files.
16+
* Concatted files are added as an StringAsset and filters get applied to concatenated string.
17+
*/
18+
class ConcatResolver implements
19+
ResolverInterface,
20+
AggregateResolverAwareInterface,
21+
AssetFilterManagerAwareInterface,
22+
MimeResolverAwareInterface
23+
{
24+
/**
25+
* @var null|ResolverInterface
26+
*/
27+
protected $aggregateResolver;
28+
29+
/**
30+
* @var null|AssetFilterManager The filterManager service.
31+
*/
32+
protected $filterManager;
33+
34+
/**
35+
* @var array the concats
36+
*/
37+
protected $concats = array();
38+
39+
/**
40+
* @var MimeResolver The mime resolver.
41+
*/
42+
protected $mimeResolver;
43+
44+
/**
45+
* Constructor
46+
*
47+
* Instantiate and optionally populate concats.
48+
*
49+
* @param array|Traversable $concats
50+
*/
51+
public function __construct($concats = array())
52+
{
53+
$this->setConcats($concats);
54+
}
55+
56+
/**
57+
* Set the mime resolver
58+
*
59+
* @param MimeResolver $resolver
60+
*/
61+
public function setMimeResolver(MimeResolver $resolver)
62+
{
63+
$this->mimeResolver = $resolver;
64+
}
65+
66+
/**
67+
* Get the mime resolver
68+
*
69+
* @return MimeResolver
70+
*/
71+
public function getMimeResolver()
72+
{
73+
return $this->mimeResolver;
74+
}
75+
76+
/**
77+
* Set (overwrite) concats
78+
*
79+
* Concats should be arrays or Traversable objects with name => path pairs
80+
*
81+
* @param array|Traversable $concats
82+
* @throws Exception\InvalidArgumentException
83+
*/
84+
public function setConcats($concats)
85+
{
86+
$this->concats = ArrayUtils::iteratorToArray($concats);
87+
}
88+
89+
/**
90+
* Set the aggregate resolver.
91+
*
92+
* @param ResolverInterface $aggregateResolver
93+
*/
94+
public function setAggregateResolver(ResolverInterface $aggregateResolver)
95+
{
96+
$this->aggregateResolver = $aggregateResolver;
97+
}
98+
99+
/**
100+
* Get the aggregate resolver.
101+
*
102+
* @return ResolverInterface
103+
*/
104+
public function getAggregateResolver()
105+
{
106+
return $this->aggregateResolver;
107+
}
108+
109+
/**
110+
* Retrieve the concats
111+
*
112+
* @return array
113+
*/
114+
public function getConcats()
115+
{
116+
return $this->concats;
117+
}
118+
119+
/**
120+
* {@inheritDoc}
121+
*/
122+
public function resolve($name)
123+
{
124+
if (!isset($this->concats[$name])) {
125+
return null;
126+
}
127+
128+
$resolvedAssets = array();
129+
130+
foreach ((array) $this->concats[$name] as $assetName) {
131+
132+
$resolvedAsset = $this->getAggregateResolver()->resolve((string) $assetName);
133+
134+
if (!$resolvedAsset instanceof AssetInterface) {
135+
throw new Exception\RuntimeException(
136+
sprintf(
137+
'Asset "%s" from collection "%s" can\'t be resolved '
138+
.'to an Asset implementing Assetic\Asset\AssetInterface.',
139+
$assetName,
140+
$name
141+
)
142+
);
143+
}
144+
145+
$resolvedAsset->mimetype = $this->getMimeResolver()->getMimeType(
146+
$resolvedAsset->getSourceRoot() . $resolvedAsset->getSourcePath()
147+
);
148+
149+
$this->getAssetFilterManager()->setFilters($assetName, $resolvedAsset);
150+
151+
$resolvedAssets[] = $resolvedAsset;
152+
}
153+
$aggregateAsset = new AggregateAsset($resolvedAssets);
154+
$this->getAssetFilterManager()->setFilters($name, $aggregateAsset);
155+
$aggregateAsset->setTargetPath($name);
156+
157+
return $aggregateAsset;
158+
}
159+
160+
/**
161+
* Set the AssetFilterManager.
162+
*
163+
* @param AssetFilterManager $filterManager
164+
*/
165+
public function setAssetFilterManager(AssetFilterManager $filterManager)
166+
{
167+
$this->filterManager = $filterManager;
168+
}
169+
170+
/**
171+
* Get the AssetFilterManager
172+
*
173+
* @return AssetFilterManager
174+
*/
175+
public function getAssetFilterManager()
176+
{
177+
return $this->filterManager;
178+
}
179+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace AssetManager\Service;
4+
5+
use Zend\ServiceManager\FactoryInterface;
6+
use Zend\ServiceManager\ServiceLocatorInterface;
7+
use AssetManager\Resolver\ConcatResolver;
8+
9+
class ConcatResolverServiceFactory implements FactoryInterface
10+
{
11+
/**
12+
* {@inheritDoc}
13+
*
14+
* @return ConcatResolver
15+
*/
16+
public function createService(ServiceLocatorInterface $serviceLocator)
17+
{
18+
$config = $serviceLocator->get('Config');
19+
$files = array();
20+
21+
if (isset($config['asset_manager']['resolver_configs']['concat'])) {
22+
$files = $config['asset_manager']['resolver_configs']['concat'];
23+
}
24+
25+
$concatResolver = new ConcatResolver($files);
26+
27+
return $concatResolver;
28+
}
29+
}

0 commit comments

Comments
 (0)