Skip to content

Commit 91ef3a4

Browse files
committed
repository & cache
1 parent 08b4426 commit 91ef3a4

File tree

6 files changed

+242
-21
lines changed

6 files changed

+242
-21
lines changed

AssetsBundle/DependencyInjection/DocplannerAssetsExtension.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,24 @@ public function load(array $configs, ContainerBuilder $container)
2121
$configuration = new Configuration();
2222
$config = $this->processConfiguration($configuration, $configs);
2323

24-
$container->setParameter('docplanner_assets.config', $config);
24+
foreach (['style', 'script'] as $type)
25+
{
26+
foreach ($config[$type]['assets'] as $assetName => &$asset)
27+
{
28+
$src = trim($asset['src']);
29+
$isNetworkResource = false;
30+
if (0 === strpos($src, '//') || false !== filter_var($src, FILTER_VALIDATE_URL))
31+
{
32+
$isNetworkResource = true;
33+
}
2534

26-
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
35+
$asset['remote'] = $isNetworkResource;
36+
}
37+
}
38+
39+
$container->setParameter('docplanner_assets.config', $config);
40+
41+
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
2742
$loader->load('services.yml');
2843
}
2944
}

AssetsBundle/IO/Asset.php

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,47 @@
88

99
class Asset
1010
{
11-
/** @var string */
12-
private $src;
11+
/** @var string|null */
12+
private $path;
1313

1414
/** @var string */
15+
private $url;
16+
17+
/** @var bool */
1518
private $inline;
1619

1720
/**
18-
* @param string $src
19-
* @param string $inline
21+
* @param string $url
22+
* @param string|null $path
23+
* @param bool $inline
2024
*/
21-
public function __construct($src, $inline)
25+
public function __construct($url, $path = null, $inline = false)
2226
{
23-
$this->src = $src;
27+
$this->url = $url;
28+
$this->path = $path;
2429
$this->inline = $inline;
2530
}
2631

2732
/**
28-
* @return string
33+
* @return string|null
2934
*/
30-
public function getSrc()
35+
public function getPath()
3136
{
32-
return $this->src;
37+
return $this->path;
3338
}
3439

3540
/**
3641
* @return string
3742
*/
38-
public function getInline()
43+
public function getUrl()
44+
{
45+
return $this->url;
46+
}
47+
48+
/**
49+
* @return boolean
50+
*/
51+
public function isInline()
3952
{
4053
return $this->inline;
4154
}

AssetsBundle/Resources/config/services.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,14 @@ services:
1616

1717
docplanner_assets.service.assets_picker:
1818
class: %docplanner_assets.service.assets_picker.class%
19-
arguments: [ @request_stack, %docplanner_assets.config% ]
19+
arguments: [ @request_stack, %docplanner_assets.config% ]
20+
21+
docplanner_assets.service.assets_repository:
22+
class: Docplanner\AssetsBundle\Service\AssetsRepository
23+
arguments: [ %docplanner_assets.config%, %kernel.cache_dir% ]
24+
25+
docplanner_assets.service.revision_warmer:
26+
class: Docplanner\AssetsBundle\Service\RevisionWarmer
27+
arguments: [ @docplanner_assets.service.assets_repository, %docplanner_assets.config% ]
28+
tags:
29+
- { name: kernel.cache_warmer }

AssetsBundle/Service/AssetsLoader.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function __construct(AssetsPicker $assetsPicker)
2626
public function renderScript($isInline = false)
2727
{
2828
$assets = $this->asstsPicker->pickScriptAssets();
29-
$mask = $type == 'inline' ? '<script>%s</script>' : '<script src="%s?%s"></script>';
29+
$mask = $isInline ? '<script>%s</script>' : '<script src="%s"></script>';
3030

3131
return $this->render($mask, $assets, $isInline);
3232
}
@@ -39,7 +39,7 @@ public function renderScript($isInline = false)
3939
public function renderStyle($isInline = false)
4040
{
4141
$assets = $this->asstsPicker->pickStyleAssets();
42-
$mask = $type == 'inline' ? '<style>%s</style>' : '<link rel="stylesheet" type="text/css" href="%s?%s">';
42+
$mask = $isInline ? '<style>%s</style>' : '<link rel="stylesheet" type="text/css" href="%s">';
4343

4444
return $this->render($mask, $assets, $isInline);
4545
}
@@ -59,19 +59,16 @@ private function render($mask, $assets, $isInline)
5959
{
6060
foreach ($assets as $asset)
6161
{
62-
if ($asset->getSrc())
63-
{
64-
$ret .= sprintf($mask, $asset->getSrc(), crc32(file_get_contents($asset->getSrc())));
65-
}
62+
$ret .= sprintf($mask, $asset->getUrl());
6663
}
6764
}
6865
else
6966
{
7067
foreach ($assets as $asset)
7168
{
72-
if ($asset->getInline())
69+
if ($asset->isInline())
7370
{
74-
$ret .= file_get_contents($asset->getInline());
71+
$ret .= file_get_contents($asset->getPath() ?: $asset->getUrl());
7572
}
7673
}
7774

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
/**
3+
* Author: Łukasz Barulski
4+
* Date: 17.09.15 16:43
5+
*/
6+
7+
namespace Docplanner\AssetsBundle\Service;
8+
9+
use Docplanner\AssetsBundle\IO\Asset;
10+
11+
class AssetsRepository
12+
{
13+
/** @var Asset[]|null */
14+
private $script;
15+
16+
/** @var Asset[]|null */
17+
private $style;
18+
19+
/** @var array */
20+
private $config;
21+
22+
/** @var array|null */
23+
private $cache;
24+
25+
/**
26+
* @param array $config
27+
* @param string $cacheDir
28+
*/
29+
public function __construct(array $config, $cacheDir)
30+
{
31+
$this->config = $config;
32+
33+
$cacheFileName = $cacheDir . '/' . RevisionWarmer::CACHE_FILE_NAME;
34+
if (file_exists($cacheFileName))
35+
{
36+
$this->cache = require $cacheFileName;
37+
}
38+
}
39+
40+
/**
41+
* @return \Docplanner\AssetsBundle\IO\Asset[]
42+
*/
43+
public function getScripts()
44+
{
45+
if (null === $this->script)
46+
{
47+
$this->script = $this->getAssets('script');
48+
}
49+
50+
return $this->script;
51+
}
52+
53+
/**
54+
* @return \Docplanner\AssetsBundle\IO\Asset[]
55+
*/
56+
public function getStyles()
57+
{
58+
if (null === $this->style)
59+
{
60+
$this->style = $this->getAssets('style');
61+
}
62+
63+
return $this->style;
64+
}
65+
66+
/**
67+
* @param string $type
68+
*
69+
* @return Asset[]
70+
*/
71+
private function getAssets($type)
72+
{
73+
$data = [];
74+
foreach ($this->config[$type]['assets'] as $assetName => $asset)
75+
{
76+
if ($asset['remote'])
77+
{
78+
$url = $asset['src'];
79+
$path = null;
80+
}
81+
else
82+
{
83+
84+
$url = $this->config['base']['host'] . $asset['src'];
85+
$path = $this->config['base']['path'] . $asset['src'];
86+
if ([] !== $this->cache && array_key_exists($type, $this->cache) && array_key_exists($assetName, $this->cache[$type]))
87+
{
88+
$url .= '?' . $this->cache[$type][$assetName];
89+
}
90+
}
91+
92+
$data[$assetName] = new Asset($url, $path, $asset['inline']);
93+
}
94+
95+
return $data;
96+
}
97+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
/**
3+
* Author: Łukasz Barulski
4+
* Date: 17.09.15 15:43
5+
*/
6+
7+
namespace Docplanner\AssetsBundle\Service;
8+
9+
use Docplanner\AssetsBundle\IO\Asset;
10+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;
11+
12+
class RevisionWarmer extends CacheWarmer
13+
{
14+
const CACHE_FILE_NAME = 'assetsRevisions.php';
15+
16+
/**
17+
* @var array
18+
*/
19+
private $config;
20+
/**
21+
* @var AssetsRepository
22+
*/
23+
private $repository;
24+
25+
/**
26+
* @param AssetsRepository $repository
27+
* @param array $config
28+
*/
29+
public function __construct(AssetsRepository $repository, array $config)
30+
{
31+
$this->repository = $repository;
32+
$this->config = $config;
33+
}
34+
35+
36+
/**
37+
* Checks whether this warmer is optional or not.
38+
* Optional warmers can be ignored on certain conditions.
39+
* A warmer should return true if the cache can be
40+
* generated incrementally and on-demand.
41+
* @return Boolean true if the warmer is optional, false otherwise
42+
*/
43+
public function isOptional()
44+
{
45+
return false;
46+
}
47+
48+
/**
49+
* Warms up the cache.
50+
*
51+
* @param string $cacheDir The cache directory
52+
*/
53+
public function warmUp($cacheDir)
54+
{
55+
$data = $this->calculateHashes();
56+
$this->createPhpFile($cacheDir, $data);
57+
}
58+
59+
/**
60+
* @return array
61+
*/
62+
private function calculateHashes()
63+
{
64+
$data = [];
65+
foreach (['script' => $this->repository->getScripts(), 'style' => $this->repository->getStyles()] as $type => $assetsList)
66+
{
67+
/** @var Asset $asset */
68+
foreach ($assetsList as $assetName => $asset)
69+
{
70+
if (null !== $asset->getPath())
71+
{
72+
$data[$type][$assetName] = crc32(file_get_contents($asset->getPath()));
73+
}
74+
}
75+
}
76+
77+
return $data;
78+
}
79+
80+
/**
81+
* @param string $cacheDir
82+
* @param array $data
83+
*/
84+
private function createPhpFile($cacheDir, array $data)
85+
{
86+
$data = '<?php' . PHP_EOL . 'return ' . var_export($data, true) . ';';
87+
$this->writeCacheFile($cacheDir . '/' . self::CACHE_FILE_NAME, $data);
88+
}
89+
}

0 commit comments

Comments
 (0)