Skip to content

Commit cccb535

Browse files
feature #35762 [Asset] Allows to download asset manifest over HTTP (GromNaN)
This PR was merged into the 5.1-dev branch. Discussion ---------- [Asset] Allows to download asset manifest over HTTP | Q | A | ------------- | --- | Branch? | master <!-- see below --> | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #35761 Fix #33001 | License | MIT | Doc PR | symfony/symfony-docs#13255 ```yaml framework: assets: json_manifest_path: 'https://cdn.example.com/manifest.json' ``` Commits ------- 4ba12a80e5 [Asset] Allows to download json manifest from a remote url
2 parents 5712486 + 6436d30 commit cccb535

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.1.0
5+
-----
6+
7+
* added `RemoteJsonManifestVersionStrategy` to download manifest over HTTP.
8+
49
4.2.0
510
-----
611

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Asset\Tests\VersionStrategy;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Asset\VersionStrategy\RemoteJsonManifestVersionStrategy;
16+
use Symfony\Component\HttpClient\Exception\JsonException;
17+
use Symfony\Component\HttpClient\MockHttpClient;
18+
use Symfony\Component\HttpClient\Response\MockResponse;
19+
20+
class RemoteJsonManifestVersionStrategyTest extends TestCase
21+
{
22+
public function testGetVersion()
23+
{
24+
$strategy = $this->createStrategy('https://cdn.example.com/manifest-valid.json');
25+
26+
$this->assertSame('main.123abc.js', $strategy->getVersion('main.js'));
27+
}
28+
29+
public function testApplyVersion()
30+
{
31+
$strategy = $this->createStrategy('https://cdn.example.com/manifest-valid.json');
32+
33+
$this->assertSame('css/styles.555def.css', $strategy->getVersion('css/styles.css'));
34+
}
35+
36+
public function testApplyVersionWhenKeyDoesNotExistInManifest()
37+
{
38+
$strategy = $this->createStrategy('https://cdn.example.com/manifest-valid.json');
39+
40+
$this->assertSame('css/other.css', $strategy->getVersion('css/other.css'));
41+
}
42+
43+
public function testMissingManifestFileThrowsException()
44+
{
45+
$this->expectException('RuntimeException');
46+
$this->expectExceptionMessage('HTTP 404 returned for "https://cdn.example.com/non-existent-file.json"');
47+
$strategy = $this->createStrategy('https://cdn.example.com/non-existent-file.json');
48+
$strategy->getVersion('main.js');
49+
}
50+
51+
public function testManifestFileWithBadJSONThrowsException()
52+
{
53+
$this->expectException(JsonException::class);
54+
$this->expectExceptionMessage('Syntax error');
55+
$strategy = $this->createStrategy('https://cdn.example.com/manifest-invalid.json');
56+
$strategy->getVersion('main.js');
57+
}
58+
59+
private function createStrategy($manifestUrl)
60+
{
61+
$httpClient = new MockHttpClient(function ($method, $url, $options) {
62+
$filename = __DIR__.'/../fixtures/'.basename($url);
63+
64+
if (file_exists($filename)) {
65+
return new MockResponse(file_get_contents($filename), ['http_headers' => ['content-type' => 'application/json']]);
66+
}
67+
68+
return new MockResponse('{}', ['http_code' => 404]);
69+
});
70+
71+
return new RemoteJsonManifestVersionStrategy($manifestUrl, $httpClient);
72+
}
73+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Asset\VersionStrategy;
13+
14+
use Symfony\Contracts\HttpClient\HttpClientInterface;
15+
16+
/**
17+
* Reads the versioned path of an asset from a remote JSON manifest file.
18+
*
19+
* For example, the manifest file might look like this:
20+
* {
21+
* "main.js": "main.abc123.js",
22+
* "css/styles.css": "css/styles.555abc.css"
23+
* }
24+
*
25+
* You could then ask for the version of "main.js" or "css/styles.css".
26+
*/
27+
class RemoteJsonManifestVersionStrategy implements VersionStrategyInterface
28+
{
29+
private $manifestData;
30+
private $manifestUrl;
31+
private $httpClient;
32+
33+
/**
34+
* @param string $manifestUrl Absolute URL to the manifest file
35+
*/
36+
public function __construct(string $manifestUrl, HttpClientInterface $httpClient)
37+
{
38+
$this->manifestUrl = $manifestUrl;
39+
$this->httpClient = $httpClient;
40+
}
41+
42+
/**
43+
* With a manifest, we don't really know or care about what
44+
* the version is. Instead, this returns the path to the
45+
* versioned file.
46+
*/
47+
public function getVersion(string $path)
48+
{
49+
return $this->applyVersion($path);
50+
}
51+
52+
public function applyVersion(string $path)
53+
{
54+
if (null === $this->manifestData) {
55+
$this->manifestData = $this->httpClient->request('GET', $this->manifestUrl, [
56+
'headers' => ['accept' => 'application/json'],
57+
])->toArray();
58+
}
59+
60+
return $this->manifestData[$path] ?? $path;
61+
}
62+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"symfony/http-foundation": ""
2323
},
2424
"require-dev": {
25+
"symfony/http-client": "^4.4|^5.0",
2526
"symfony/http-foundation": "^4.4|^5.0",
2627
"symfony/http-kernel": "^4.4|^5.0"
2728
},

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy