Skip to content

Commit 64f1e94

Browse files
committed
Adding Autowireable interfaces & docs for reset()
1 parent c24310a commit 64f1e94

File tree

7 files changed

+128
-6
lines changed

7 files changed

+128
-6
lines changed

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,43 @@ and `build/entry1.js`, then `encore_entry_script_tags()` is equivalent to:
9292
If you want more control, you can use the `encore_entry_js_files()` and
9393
`encore_entry_css_files()` methods to get the list of files needed, then
9494
loop and create the `script` and `link` tags manually.
95+
96+
## Rendering Multiple Times in a Request (e.g. to Generate a PDF)
97+
98+
When you render your script or link tags, the bundle is smart enough
99+
not to repeat the same JavaScript or CSS file within the same request.
100+
This prevents you from having duplicate `<link>` or `<script>` tags
101+
if you render multiple entries that both rely on the same file.
102+
103+
In some cases, however, you may want to render the script & link
104+
tags for the same entry multiple times in a request. For example,
105+
if you render multiple Twig templates to create multiple PDF files
106+
during a single request.
107+
108+
In that case, before each render, you'll need to "reset" the internal
109+
cache so that the bundle re-renders CSS or JS files that it previously
110+
rendered. For example, in a controller:
111+
112+
```php
113+
// src/Controller/SomeController.php
114+
115+
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
116+
117+
class SomeController
118+
{
119+
public function index(EntrypointLookupInterface $entrypointLookup)
120+
{
121+
$entrypointLookup->reset();
122+
// render a template
123+
124+
$entrypointLookup->reset();
125+
// render another template
126+
127+
// ...
128+
}
129+
}
130+
```
131+
132+
If you have multiple builds, you can also autowire
133+
`Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollectionInterface`
134+
and use it to get the `EntrypointLookupInterface` object for any build.

src/Asset/EntrypointLookupCollection.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,30 @@
1919
*
2020
* @final
2121
*/
22-
class EntrypointLookupCollection
22+
class EntrypointLookupCollection implements EntrypointLookupCollectionInterface
2323
{
2424
private $buildEntrypoints;
2525

26-
public function __construct(ContainerInterface $buildEntrypoints)
26+
private $defaultBuildName;
27+
28+
public function __construct(ContainerInterface $buildEntrypoints, string $defaultBuildName = null)
2729
{
2830
$this->buildEntrypoints = $buildEntrypoints;
31+
$this->defaultBuildName = $defaultBuildName;
2932
}
3033

31-
public function getEntrypointLookup(string $buildName): EntrypointLookupInterface
34+
public function getEntrypointLookup(string $buildName = null): EntrypointLookupInterface
3235
{
36+
if (null === $buildName) {
37+
if (null === $this->defaultBuildName) {
38+
throw new UndefinedBuildException('There is no default build configured: please pass an argument to getEntrypointLookup().');
39+
}
40+
41+
$buildName = $this->defaultBuildName;
42+
}
43+
3344
if (!$this->buildEntrypoints->has($buildName)) {
34-
throw new UndefinedBuildException(sprintf('Given entry point "%s" is not configured', $buildName));
45+
throw new UndefinedBuildException(sprintf('The build "%s" is not configured', $buildName));
3546
}
3647

3748
return $this->buildEntrypoints->get($buildName);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony WebpackEncoreBundle package.
5+
* (c) Fabien Potencier <[email protected]>
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace Symfony\WebpackEncoreBundle\Asset;
11+
12+
use Symfony\WebpackEncoreBundle\Exception\UndefinedBuildException;
13+
14+
interface EntrypointLookupCollectionInterface
15+
{
16+
/**
17+
* Retrieve the EntrypointLookupInterface for the given build.
18+
*
19+
* @throws UndefinedBuildException If the build does not exist.
20+
*/
21+
public function getEntrypointLookup(string $buildName = null): EntrypointLookupInterface;
22+
}

src/DependencyInjection/WebpackEncoreExtension.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
namespace Symfony\WebpackEncoreBundle\DependencyInjection;
1111

1212
use Symfony\Component\Config\FileLocator;
13+
use Symfony\Component\DependencyInjection\Alias;
1314
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516
use Symfony\Component\DependencyInjection\Definition;
1617
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1718
use Symfony\Component\DependencyInjection\Reference;
1819
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
1920
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookup;
21+
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
2022

2123
final class WebpackEncoreExtension extends Extension
2224
{
@@ -46,14 +48,20 @@ public function load(array $configs, ContainerBuilder $container)
4648

4749
$container->getDefinition('webpack_encore.entrypoint_lookup_collection')
4850
->replaceArgument(0, ServiceLocatorTagPass::register($container, $factories));
51+
$container->setAlias(EntrypointLookupInterface::class, new Alias($this->getEntrypointServiceId('_default')));
4952
}
5053

5154
private function entrypointFactory(ContainerBuilder $container, string $name, string $path, bool $cacheEnabled): Reference
5255
{
53-
$id = sprintf('webpack_encore.entrypoint_lookup[%s]', $name);
56+
$id = $this->getEntrypointServiceId($name);
5457
$arguments = [$path.'/'.self::ENTRYPOINTS_FILE_NAME, $cacheEnabled ? new Reference('webpack_encore.cache') : null, $name];
5558
$container->setDefinition($id, new Definition(EntrypointLookup::class, $arguments));
5659

5760
return new Reference($id);
5861
}
62+
63+
private function getEntrypointServiceId(string $name): string
64+
{
65+
return sprintf('webpack_encore.entrypoint_lookup[%s]', $name);
66+
}
5967
}

src/Resources/config/services.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
<argument /> <!-- build list of entrypoints locator -->
1212
</service>
1313

14+
<service id="Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollectionInterface" alias="webpack_encore.entrypoint_lookup_collection" />
15+
1416
<service id="webpack_encore.tag_renderer" class="Symfony\WebpackEncoreBundle\Asset\TagRenderer">
1517
<argument type="service" id="webpack_encore.entrypoint_lookup_collection" />
1618
<argument type="service" id="assets.packages" />

tests/Asset/EntrypointLookupCollectionTest.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,35 @@
55
use Symfony\Component\DependencyInjection\ServiceLocator;
66
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollection;
77
use PHPUnit\Framework\TestCase;
8+
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
89

910
class EntrypointLookupCollectionTest extends TestCase
1011
{
1112
/**
1213
* @expectedException Symfony\WebpackEncoreBundle\Exception\UndefinedBuildException
13-
* @expectedExceptionMessage Given entry point "something" is not configured
14+
* @expectedExceptionMessage The build "something" is not configured
1415
*/
1516
public function testExceptionOnMissingEntry()
1617
{
1718
$collection = new EntrypointLookupCollection(new ServiceLocator([]));
1819
$collection->getEntrypointLookup('something');
1920
}
21+
22+
/**
23+
* @expectedException Symfony\WebpackEncoreBundle\Exception\UndefinedBuildException
24+
* @expectedExceptionMessage There is no default build configured: please pass an argument to getEntrypointLookup().
25+
*/
26+
public function testExceptionOnMissingDefaultBuildEntry()
27+
{
28+
$collection = new EntrypointLookupCollection(new ServiceLocator([]));
29+
$collection->getEntrypointLookup();
30+
}
31+
32+
public function testDefaultBuildIsReturned()
33+
{
34+
$lookup = $this->createMock(EntrypointLookupInterface::class);
35+
$collection = new EntrypointLookupCollection(new ServiceLocator(['the_default' => function() use ($lookup) { return $lookup; }]), 'the_default');
36+
37+
$this->assertSame($lookup, $collection->getEntrypointLookup());
38+
}
2039
}

tests/IntegrationTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Symfony\WebpackEncoreBundle\Tests;
44

55
use Symfony\Component\DependencyInjection\Reference;
6+
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollectionInterface;
7+
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
68
use Symfony\WebpackEncoreBundle\CacheWarmer\EntrypointCacheWarmer;
79
use Symfony\WebpackEncoreBundle\WebpackEncoreBundle;
810
use PHPUnit\Framework\TestCase;
@@ -96,6 +98,14 @@ public function testCacheWarmer()
9698
// check for both build keys
9799
$this->assertEquals(['_default' => 0, 'different_build' => 1], $data[0]);
98100
}
101+
102+
public function testAutowireableInterfaces()
103+
{
104+
$kernel = new WebpackEncoreIntegrationTestKernel(true);
105+
$kernel->boot();
106+
$container = $kernel->getContainer();
107+
$this->assertInstanceOf(WebpackEncoreAutowireTestService::class, $container->get(WebpackEncoreAutowireTestService::class));
108+
}
99109
}
100110

101111
class WebpackEncoreIntegrationTestKernel extends Kernel
@@ -145,6 +155,9 @@ public function registerContainerConfiguration(LoaderInterface $loader)
145155
$container->register(WebpackEncoreCacheWarmerTester::class)
146156
->addArgument(new Reference('webpack_encore.entrypoint_lookup.cache_warmer'))
147157
->setPublic(true);
158+
159+
$container->autowire(WebpackEncoreAutowireTestService::class)
160+
->setPublic(true);
148161
});
149162
}
150163

@@ -173,3 +186,10 @@ public function warmCache(string $cacheDir)
173186
$this->entrypointCacheWarmer->warmUp($cacheDir);
174187
}
175188
}
189+
190+
class WebpackEncoreAutowireTestService
191+
{
192+
public function __construct(EntrypointLookupInterface $entrypointLookup, EntrypointLookupCollectionInterface $entrypointLookupCollection)
193+
{
194+
}
195+
}

0 commit comments

Comments
 (0)