[Asset] Allows to download json manifest from a remote url
Handle URL in json_manifest_path Download the manifest using the HttpClient
This commit is contained in:
parent
7995fed10b
commit
4ba12a80e5
@ -1049,7 +1049,12 @@ class FrameworkExtension extends Extension
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $jsonManifestPath) {
|
if (null !== $jsonManifestPath) {
|
||||||
$def = new ChildDefinition('assets.json_manifest_version_strategy');
|
$definitionName = 'assets.json_manifest_version_strategy';
|
||||||
|
if (0 === strpos(parse_url($jsonManifestPath, PHP_URL_SCHEME), 'http')) {
|
||||||
|
$definitionName = 'assets.remote_json_manifest_version_strategy';
|
||||||
|
}
|
||||||
|
|
||||||
|
$def = new ChildDefinition($definitionName);
|
||||||
$def->replaceArgument(0, $jsonManifestPath);
|
$def->replaceArgument(0, $jsonManifestPath);
|
||||||
$container->setDefinition('assets._version_'.$name, $def);
|
$container->setDefinition('assets._version_'.$name, $def);
|
||||||
|
|
||||||
|
@ -50,5 +50,10 @@
|
|||||||
<service id="assets.json_manifest_version_strategy" class="Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy" abstract="true">
|
<service id="assets.json_manifest_version_strategy" class="Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy" abstract="true">
|
||||||
<argument /> <!-- manifest path -->
|
<argument /> <!-- manifest path -->
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="assets.remote_json_manifest_version_strategy" class="Symfony\Component\Asset\VersionStrategy\RemoteJsonManifestVersionStrategy" abstract="true">
|
||||||
|
<argument /> <!-- manifest url -->
|
||||||
|
<argument type="service" id="http_client" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -27,6 +27,9 @@ $container->loadFromExtension('framework', [
|
|||||||
'json_manifest_strategy' => [
|
'json_manifest_strategy' => [
|
||||||
'json_manifest_path' => '/path/to/manifest.json',
|
'json_manifest_path' => '/path/to/manifest.json',
|
||||||
],
|
],
|
||||||
|
'remote_manifest' => [
|
||||||
|
'json_manifest_path' => 'https://cdn.example.com/manifest.json',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<framework:base-url>https://bar_version_strategy.example.com</framework:base-url>
|
<framework:base-url>https://bar_version_strategy.example.com</framework:base-url>
|
||||||
</framework:package>
|
</framework:package>
|
||||||
<framework:package name="json_manifest_strategy" json-manifest-path="/path/to/manifest.json" />
|
<framework:package name="json_manifest_strategy" json-manifest-path="/path/to/manifest.json" />
|
||||||
|
<framework:package name="remote_manifest" json-manifest-path="https://cdn.example.com/manifest.json" />
|
||||||
</framework:assets>
|
</framework:assets>
|
||||||
</framework:config>
|
</framework:config>
|
||||||
</container>
|
</container>
|
||||||
|
@ -19,3 +19,5 @@ framework:
|
|||||||
version_strategy: assets.custom_version_strategy
|
version_strategy: assets.custom_version_strategy
|
||||||
json_manifest_strategy:
|
json_manifest_strategy:
|
||||||
json_manifest_path: '/path/to/manifest.json'
|
json_manifest_path: '/path/to/manifest.json'
|
||||||
|
remote_manifest:
|
||||||
|
json_manifest_path: 'https://cdn.example.com/manifest.json'
|
||||||
|
@ -535,7 +535,7 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
|
|
||||||
// packages
|
// packages
|
||||||
$packages = $packages->getArgument(1);
|
$packages = $packages->getArgument(1);
|
||||||
$this->assertCount(6, $packages);
|
$this->assertCount(7, $packages);
|
||||||
|
|
||||||
$package = $container->getDefinition((string) $packages['images_path']);
|
$package = $container->getDefinition((string) $packages['images_path']);
|
||||||
$this->assertPathPackage($container, $package, '/foo', 'SomeVersionScheme', '%%s?version=%%s');
|
$this->assertPathPackage($container, $package, '/foo', 'SomeVersionScheme', '%%s?version=%%s');
|
||||||
@ -556,6 +556,11 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$versionStrategy = $container->getDefinition((string) $package->getArgument(1));
|
$versionStrategy = $container->getDefinition((string) $package->getArgument(1));
|
||||||
$this->assertEquals('assets.json_manifest_version_strategy', $versionStrategy->getParent());
|
$this->assertEquals('assets.json_manifest_version_strategy', $versionStrategy->getParent());
|
||||||
$this->assertEquals('/path/to/manifest.json', $versionStrategy->getArgument(0));
|
$this->assertEquals('/path/to/manifest.json', $versionStrategy->getArgument(0));
|
||||||
|
|
||||||
|
$package = $container->getDefinition($packages['remote_manifest']);
|
||||||
|
$versionStrategy = $container->getDefinition($package->getArgument(1));
|
||||||
|
$this->assertSame('assets.remote_json_manifest_version_strategy', $versionStrategy->getParent());
|
||||||
|
$this->assertSame('https://cdn.example.com/manifest.json', $versionStrategy->getArgument(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAssetsDefaultVersionStrategyAsService()
|
public function testAssetsDefaultVersionStrategyAsService()
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/annotations": "~1.7",
|
"doctrine/annotations": "~1.7",
|
||||||
"doctrine/cache": "~1.0",
|
"doctrine/cache": "~1.0",
|
||||||
"symfony/asset": "^4.4|^5.0",
|
"symfony/asset": "^5.1",
|
||||||
"symfony/browser-kit": "^4.4|^5.0",
|
"symfony/browser-kit": "^4.4|^5.0",
|
||||||
"symfony/console": "^4.4|^5.0",
|
"symfony/console": "^4.4|^5.0",
|
||||||
"symfony/css-selector": "^4.4|^5.0",
|
"symfony/css-selector": "^4.4|^5.0",
|
||||||
@ -68,7 +68,7 @@
|
|||||||
"phpdocumentor/reflection-docblock": "<3.0",
|
"phpdocumentor/reflection-docblock": "<3.0",
|
||||||
"phpdocumentor/type-resolver": "<0.2.1",
|
"phpdocumentor/type-resolver": "<0.2.1",
|
||||||
"phpunit/phpunit": "<5.4.3",
|
"phpunit/phpunit": "<5.4.3",
|
||||||
"symfony/asset": "<4.4",
|
"symfony/asset": "<5.1",
|
||||||
"symfony/browser-kit": "<4.4",
|
"symfony/browser-kit": "<4.4",
|
||||||
"symfony/console": "<4.4",
|
"symfony/console": "<4.4",
|
||||||
"symfony/dotenv": "<5.1",
|
"symfony/dotenv": "<5.1",
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
5.1.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added `RemoteJsonManifestVersionStrategy` to download manifest over HTTP.
|
||||||
|
|
||||||
4.2.0
|
4.2.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Asset\Tests\VersionStrategy;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Asset\VersionStrategy\RemoteJsonManifestVersionStrategy;
|
||||||
|
use Symfony\Component\HttpClient\Exception\JsonException;
|
||||||
|
use Symfony\Component\HttpClient\MockHttpClient;
|
||||||
|
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||||
|
|
||||||
|
class RemoteJsonManifestVersionStrategyTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testGetVersion()
|
||||||
|
{
|
||||||
|
$strategy = $this->createStrategy('https://cdn.example.com/manifest-valid.json');
|
||||||
|
|
||||||
|
$this->assertSame('main.123abc.js', $strategy->getVersion('main.js'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApplyVersion()
|
||||||
|
{
|
||||||
|
$strategy = $this->createStrategy('https://cdn.example.com/manifest-valid.json');
|
||||||
|
|
||||||
|
$this->assertSame('css/styles.555def.css', $strategy->getVersion('css/styles.css'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApplyVersionWhenKeyDoesNotExistInManifest()
|
||||||
|
{
|
||||||
|
$strategy = $this->createStrategy('https://cdn.example.com/manifest-valid.json');
|
||||||
|
|
||||||
|
$this->assertSame('css/other.css', $strategy->getVersion('css/other.css'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMissingManifestFileThrowsException()
|
||||||
|
{
|
||||||
|
$this->expectException('RuntimeException');
|
||||||
|
$this->expectExceptionMessage('HTTP 404 returned for "https://cdn.example.com/non-existent-file.json"');
|
||||||
|
$strategy = $this->createStrategy('https://cdn.example.com/non-existent-file.json');
|
||||||
|
$strategy->getVersion('main.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testManifestFileWithBadJSONThrowsException()
|
||||||
|
{
|
||||||
|
$this->expectException(JsonException::class);
|
||||||
|
$this->expectExceptionMessage('Syntax error');
|
||||||
|
$strategy = $this->createStrategy('https://cdn.example.com/manifest-invalid.json');
|
||||||
|
$strategy->getVersion('main.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createStrategy($manifestUrl)
|
||||||
|
{
|
||||||
|
$httpClient = new MockHttpClient(function ($method, $url, $options) {
|
||||||
|
$filename = __DIR__.'/../fixtures/'.basename($url);
|
||||||
|
|
||||||
|
if (file_exists($filename)) {
|
||||||
|
return new MockResponse(file_get_contents($filename), ['http_headers' => ['content-type' => 'application/json']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MockResponse('{}', ['http_code' => 404]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return new RemoteJsonManifestVersionStrategy($manifestUrl, $httpClient);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Asset\VersionStrategy;
|
||||||
|
|
||||||
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the versioned path of an asset from a remote JSON manifest file.
|
||||||
|
*
|
||||||
|
* For example, the manifest file might look like this:
|
||||||
|
* {
|
||||||
|
* "main.js": "main.abc123.js",
|
||||||
|
* "css/styles.css": "css/styles.555abc.css"
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* You could then ask for the version of "main.js" or "css/styles.css".
|
||||||
|
*/
|
||||||
|
class RemoteJsonManifestVersionStrategy implements VersionStrategyInterface
|
||||||
|
{
|
||||||
|
private $manifestData;
|
||||||
|
private $manifestUrl;
|
||||||
|
private $httpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $manifestUrl Absolute URL to the manifest file
|
||||||
|
*/
|
||||||
|
public function __construct(string $manifestUrl, HttpClientInterface $httpClient)
|
||||||
|
{
|
||||||
|
$this->manifestUrl = $manifestUrl;
|
||||||
|
$this->httpClient = $httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With a manifest, we don't really know or care about what
|
||||||
|
* the version is. Instead, this returns the path to the
|
||||||
|
* versioned file.
|
||||||
|
*/
|
||||||
|
public function getVersion(string $path)
|
||||||
|
{
|
||||||
|
return $this->applyVersion($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyVersion(string $path)
|
||||||
|
{
|
||||||
|
if (null === $this->manifestData) {
|
||||||
|
$this->manifestData = $this->httpClient->request('GET', $this->manifestUrl, [
|
||||||
|
'headers' => ['accept' => 'application/json'],
|
||||||
|
])->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->manifestData[$path] ?? $path;
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@
|
|||||||
"symfony/http-foundation": ""
|
"symfony/http-foundation": ""
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"symfony/http-client": "^4.4|^5.0",
|
||||||
"symfony/http-foundation": "^4.4|^5.0",
|
"symfony/http-foundation": "^4.4|^5.0",
|
||||||
"symfony/http-kernel": "^4.4|^5.0"
|
"symfony/http-kernel": "^4.4|^5.0"
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user