8000 [Asset] Allows to download asset manifest over HTTP by GromNaN · Pull Request #35762 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Asset] Allows to download asset manifest over HTTP #35762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,12 @@ private function createVersion(ContainerBuilder $container, ?string $version, ?s
}

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);
$container->setDefinition('assets._version_'.$name, $def);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,10 @@
<service id="assets.json_manifest_version_strategy" class="Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy" abstract="true">
<argument /> <!-- manifest path -->
</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>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
'json_manifest_strategy' => [
'json_manifest_path' => '/path/to/manifest.json',
],
'remote_manifest' => [
'json_manifest_path' => 'https://cdn.example.com/manifest.json',
],
],
],
]);
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<framework:base-url>https://bar_version_strategy.example.com</framework:base-url>
</framework:package>
<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:config>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ framework:
version_strategy: assets.custom_version_strategy
json_manifest_strategy:
json_manifest_path: '/path/to/manifest.json'
remote_manifest:
json_manifest_path: 'https://cdn.example.com/manifest.json'
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ public function testAssets()

// packages
$packages = $packages->getArgument(1);
$this->assertCount(6, $packages);
$this->assertCount(7, $packages);

$package = $container->getDefinition((string) $packages['images_path']);
$this->assertPathPackage($container, $package, '/foo', 'SomeVersionScheme', '%%s?version=%%s');
Expand All @@ -556,6 +556,11 @@ public function testAssets()
$versionStrategy = $container->getDefinition((string) $package->getArgument(1));
$this->assertEquals('assets.json_manifest_version_strategy', $versionStrategy->getParent());
$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()
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"require-dev": {
"doctrine/annotations": "~1.7",
"doctrine/cache": "~1.0",
"symfony/asset": "^4.4|^5.0",
"symfony/asset": "^5.1",
"symfony/browser-kit": "^4.4|^5.0",
"symfony/console": "^4.4|^5.0",
"symfony/css-selector": "^4.4|^5.0",
Expand Down Expand Up @@ -68,7 +68,7 @@
"phpdocumentor/reflection-docblock": "<3.0",
"phpdocumentor/type-resolver": "<0.2.1",
"phpunit/phpunit": "<5.4.3",
"symfony/asset": "<4.4",
"symfony/asset": "<5.1",
"symfony/browser-kit": "<4.4",
"symfony/console": "<4.4",
"symfony/dotenv": "<5.1",
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Asset/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

5.1.0
-----

* added `RemoteJsonManifestVersionStrategy` to download manifest over HTTP.

4.2.0
-----

Expand Down
Original file line number Diff line number Diff line change
@@ -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
F438 {
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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/Asset/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"symfony/http-foundation": ""
},
"require-dev": {
"symfony/http-client": "^4.4|^5.0",
"symfony/http-foundation": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0"
},
Expand Down
0