Skip to content

Commit 94e0be9

Browse files
committed
NEXT-39502 - Skip adding asset packages if APP_URL env variable is not set
1 parent 2ada34b commit 94e0be9

File tree

11 files changed

+127
-61
lines changed

11 files changed

+127
-61
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Thumbs.db
1212

1313
# PhpStorm-Project
1414
/.idea/
15+
!/.idea/icon.svg
1516
/.fleet/
1617
*.http
1718
/.run/

.idea/icon.svg

+10
Loading

src/Core/Framework/Adapter/AdapterException.php

+15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Shopware\Core\Framework\HttpException;
66
use Shopware\Core\Framework\Log\Package;
7+
use Symfony\Component\Asset\Exception\InvalidArgumentException;
78
use Symfony\Component\HttpFoundation\Response;
89
use Twig\Node\Expression\AbstractExpression;
910

@@ -23,6 +24,7 @@ class AdapterException extends HttpException
2324
* @internal
2425
*/
2526
public const REDIS_MISSING_CONNECTION_PARAMETER = 'FRAMEWORK__REDIS_MISSING_CONNECTION_PARAMETER';
27+
public const INVALID_ASSET_URL = 'FRAMEWORK__INVALID_ASSET_URL';
2628

2729
public static function unexpectedTwigExpression(AbstractExpression $expression): self
2830
{
@@ -123,4 +125,17 @@ public static function missingRedisConnectionParameter(?string $connectionName,
123125
],
124126
);
125127
}
128+
129+
public static function invalidAssetUrl(InvalidArgumentException $previous): self
130+
{
131+
return new self(
132+
Response::HTTP_INTERNAL_SERVER_ERROR,
133+
self::INVALID_ASSET_URL,
134+
'Invalid asset URL. Check the "APP_URL" environment variable. Error message: {{ message }}',
135+
[
136+
'message' => $previous->getMessage(),
137+
],
138+
$previous
139+
);
140+
}
126141
}

src/Core/Framework/Adapter/Asset/AssetPackageService.php

+19-7
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,43 @@
22

33
namespace Shopware\Core\Framework\Adapter\Asset;
44

5+
use Shopware\Core\DevOps\Environment\EnvironmentHelper;
6+
use Shopware\Core\Framework\Adapter\AdapterException;
7+
use Shopware\Core\Framework\Log\Package;
58
use Shopware\Core\Framework\Plugin\Util\AssetService;
6-
use Symfony\Component\Asset\Package;
9+
use Symfony\Component\Asset\Exception\InvalidArgumentException;
10+
use Symfony\Component\Asset\Package as AssetPackage;
711
use Symfony\Component\Asset\Packages;
812
use Symfony\Component\Asset\UrlPackage;
913
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
1014

11-
#[\Shopware\Core\Framework\Log\Package('core')]
15+
#[Package('core')]
1216
class AssetPackageService
1317
{
1418
/**
1519
* @param array<string, string> $bundleMap
1620
*/
17-
public static function create(array $bundleMap, Package $package, VersionStrategyInterface $versionStrategy, mixed ...$args): Packages
21+
public static function create(array $bundleMap, AssetPackage $package, VersionStrategyInterface $versionStrategy, mixed ...$args): Packages
1822
{
1923
$packages = new Packages(...$args);
2024

25+
if (!EnvironmentHelper::hasVariable('APP_URL')) {
26+
return $packages;
27+
}
28+
2129
foreach ($bundleMap as $bundleName => $bundlePath) {
2230
/** @see AssetService::getTargetDirectory() */
2331
$targetPath = '/bundles/' . preg_replace('/bundle$/', '', mb_strtolower($bundleName));
2432

2533
$path = $package->getUrl($targetPath);
26-
$packages->addPackage(
27-
'@' . $bundleName,
28-
new UrlPackage($path, new PrefixVersionStrategy($targetPath, $versionStrategy))
29-
);
34+
35+
try {
36+
$bundlePackage = new UrlPackage($path, new PrefixVersionStrategy($targetPath, $versionStrategy));
37+
} catch (InvalidArgumentException $exception) {
38+
throw AdapterException::invalidAssetUrl($exception);
39+
}
40+
41+
$packages->addPackage('@' . $bundleName, $bundlePackage);
3042
}
3143

3244
return $packages;

src/Core/Framework/Adapter/Asset/FallbackUrlPackage.php

+8-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class FallbackUrlPackage extends UrlPackage
1515
/**
1616
* @internal
1717
*
18-
* @param string|string[] $baseUrls
18+
* @param string|list<string> $baseUrls
1919
*/
2020
public function __construct(
2121
string|array $baseUrls,
@@ -30,27 +30,26 @@ public function __construct(
3030
}
3131

3232
/**
33-
* @param string[] $baseUrls
33+
* @param list<string> $baseUrls
3434
*
35-
* @return string[]
35+
* @return list<string>
3636
*/
3737
private function applyFallback(array $baseUrls): array
3838
{
39-
$request = $this->requestStack?->getMainRequest() ?? new Request([], [], [], [], [], $_SERVER);
39+
$request = $this->requestStack?->getMainRequest() ?? new Request(server: $_SERVER);
4040

41-
$basePath = $request->getSchemeAndHttpHost() . $request->getBasePath();
42-
$requestUrl = rtrim($basePath, '/') . '/';
43-
44-
if ($request->getHost() === '' && EnvironmentHelper::hasVariable('APP_URL')) {
41+
if ($request->getHost() === '') {
4542
$requestUrl = EnvironmentHelper::getVariable('APP_URL');
43+
} else {
44+
$basePath = $request->getSchemeAndHttpHost() . $request->getBasePath();
45+
$requestUrl = rtrim($basePath, '/') . '/';
4646
}
4747

4848
foreach ($baseUrls as &$url) {
4949
if ($url === '') {
5050
$url = $requestUrl;
5151
}
5252
}
53-
5453
unset($url);
5554

5655
return $baseUrls;

src/Core/Framework/DependencyInjection/CompilerPass/AssetBundleRegistrationCompilerPass.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ public function process(ContainerBuilder $container): void
3636
array_unshift($arguments, new Reference('shopware.asset.asset_without_versioning'));
3737
array_unshift($arguments, $bundleMap);
3838

39-
$assetService->setArguments(
40-
$arguments
41-
);
39+
$assetService->setArguments($arguments);
4240
}
4341
}

src/Storefront/Theme/ThemeAssetPackage.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ThemeAssetPackage extends FallbackUrlPackage
1515
/**
1616
* @internal
1717
*
18-
* @param string|string[] $baseUrls
18+
* @param string|list<string> $baseUrls
1919
*/
2020
public function __construct(
2121
string|array $baseUrls,

tests/unit/Core/Framework/Adapter/Asset/AssetPackageServiceTest.php

+49-21
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,76 @@
44

55
use PHPUnit\Framework\Attributes\CoversClass;
66
use PHPUnit\Framework\TestCase;
7+
use Shopware\Core\Framework\Adapter\AdapterException;
78
use Shopware\Core\Framework\Adapter\Asset\AssetPackageService;
9+
use Shopware\Core\Framework\Adapter\Asset\FallbackUrlPackage;
10+
use Shopware\Core\Framework\Test\TestCaseBase\EnvTestBehaviour;
811
use Symfony\Component\Asset\Package;
12+
use Symfony\Component\Asset\Packages;
913
use Symfony\Component\Asset\UrlPackage;
1014
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\RequestStack;
1117

1218
/**
1319
* @internal
1420
*/
1521
#[CoversClass(AssetPackageService::class)]
1622
class AssetPackageServiceTest extends TestCase
1723
{
18-
public function testCreate(): void
24+
use EnvTestBehaviour;
25+
26+
public function testCreateWithRequest(): void
1927
{
20-
$bundleMap = [
21-
'TestBundle' => '/var/www/html/vendor/shopware/core/TestBundle',
22-
'TestPlugin' => '/var/www/html/custom/plugins/TestPlugin',
23-
];
28+
$requestStack = new RequestStack();
29+
$requestStack->push(Request::create('https://test.de'));
30+
31+
$packages = $this->getPackages($requestStack);
2432

25-
$package = $this->createMock(Package::class);
26-
$package->method('getUrl')
27-
->willReturnCallback(static function (string $path): string {
28-
$urls = [
29-
// bundle prefix should be removed @see AssetService::getTargetDirectory
30-
// and the path should be lowercased
31-
'/bundles/test' => 'http://localhost/bundles/test',
32-
'/bundles/testplugin' => 'http://localhost/bundles/testplugin',
33-
];
33+
$bundlePackage = $packages->getPackage('@TestBundle');
34+
static::assertInstanceOf(UrlPackage::class, $bundlePackage);
35+
static::assertSame('https://test.de/bundles/test/foo', $bundlePackage->getUrl('/foo'));
3436

35-
return $urls[$path];
36-
});
37+
$pluginPackage = $packages->getPackage('@TestPlugin');
38+
static::assertInstanceOf(UrlPackage::class, $pluginPackage);
39+
static::assertSame('https://test.de/bundles/testplugin/foo', $pluginPackage->getUrl('/foo'));
40+
}
3741

38-
$defaultPackage = new Package(new EmptyVersionStrategy());
39-
$packages = AssetPackageService::create($bundleMap, $package, new EmptyVersionStrategy(), $defaultPackage);
42+
public function testCreateWithAppUrl(): void
43+
{
44+
$this->setEnvVars(['APP_URL' => 'https://test.de']);
4045

41-
static::assertSame($defaultPackage, $packages->getPackage());
46+
$packages = $this->getPackages();
4247

4348
$bundlePackage = $packages->getPackage('@TestBundle');
4449
static::assertInstanceOf(UrlPackage::class, $bundlePackage);
45-
static::assertSame('http://localhost/bundles/test/foo', $bundlePackage->getUrl('/foo'));
50+
static::assertSame('https://test.de/bundles/test/foo', $bundlePackage->getUrl('/foo'));
4651

4752
$pluginPackage = $packages->getPackage('@TestPlugin');
4853
static::assertInstanceOf(UrlPackage::class, $pluginPackage);
49-
static::assertSame('http://localhost/bundles/testplugin/foo', $pluginPackage->getUrl('/foo'));
54+
static::assertSame('https://test.de/bundles/testplugin/foo', $pluginPackage->getUrl('/foo'));
55+
}
56+
57+
public function testCreateWithoutAppUrl(): void
58+
{
59+
$this->setEnvVars(['APP_URL' => '']);
60+
$this->expectException(AdapterException::class);
61+
$this->expectExceptionMessage('Invalid asset URL. Check the "APP_URL" environment variable. Error message: "/bundles/test" is not a valid URL.');
62+
$this->getPackages();
63+
}
64+
65+
private function getPackages(?RequestStack $requestStack = null): Packages
66+
{
67+
$emptyVersionStrategy = new EmptyVersionStrategy();
68+
69+
return AssetPackageService::create(
70+
[
71+
'TestBundle' => '/var/www/html/vendor/shopware/core/TestBundle',
72+
'TestPlugin' => '/var/www/html/custom/plugins/TestPlugin',
73+
],
74+
new FallbackUrlPackage('', $emptyVersionStrategy, $requestStack),
75+
$emptyVersionStrategy,
76+
new Package($emptyVersionStrategy)
77+
);
5078
}
5179
}

tests/unit/Core/Framework/Adapter/Redis/RedisConnectionsCompilerPassTest.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public function testProcessConfiguresProvider(): void
7777
$locatorDefinition = $this->containerBuilder->getDefinition((string) $locatorArgument);
7878
$className = $locatorDefinition->getClass();
7979
static::assertIsString($className);
80-
static::assertArrayHasKey(ContainerInterface::class, class_implements($className));
80+
$interfaces = class_implements($className);
81+
static::assertIsArray($interfaces);
82+
static::assertArrayHasKey(ContainerInterface::class, $interfaces);
8183
}
8284
}

tests/unit/Core/Framework/Asset/FallbackUrlPackageTest.php

+18-17
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
use PHPUnit\Framework\Attributes\CoversClass;
66
use PHPUnit\Framework\TestCase;
7+
use Shopware\Core\DevOps\Environment\EnvironmentHelper;
78
use Shopware\Core\Framework\Adapter\Asset\FallbackUrlPackage;
89
use Shopware\Core\Framework\Log\Package;
10+
use Shopware\Core\Framework\Test\TestCaseBase\EnvTestBehaviour;
911
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
1012
use Symfony\Component\HttpFoundation\Request;
1113
use Symfony\Component\HttpFoundation\RequestStack;
@@ -17,43 +19,42 @@
1719
#[CoversClass(FallbackUrlPackage::class)]
1820
class FallbackUrlPackageTest extends TestCase
1921
{
22+
use EnvTestBehaviour;
23+
2024
public function testCliFallbacksToAppUrl(): void
2125
{
22-
$package = new FallbackUrlPackage([''], new EmptyVersionStrategy());
23-
$url = $package->getUrl('test');
26+
$url = $this->createPackage()->getUrl('test');
2427

25-
static::assertSame($_SERVER['APP_URL'] . '/test', $url);
28+
static::assertSame(EnvironmentHelper::getVariable('APP_URL') . '/test', $url);
2629
}
2730

2831
public function testCliUrlGiven(): void
2932
{
30-
$package = new FallbackUrlPackage(['http://shopware.com'], new EmptyVersionStrategy());
31-
$url = $package->getUrl('test');
33+
$url = $this->createPackage('https://shopware.com')->getUrl('test');
3234

33-
static::assertSame('http://shopware.com/test', $url);
35+
static::assertSame('https://shopware.com/test', $url);
3436
}
3537

3638
public function testWebFallbackToRequest(): void
3739
{
38-
$_SERVER['HTTP_HOST'] = 'test.de';
39-
$package = new FallbackUrlPackage([''], new EmptyVersionStrategy());
40-
$url = $package->getUrl('test');
40+
$this->setEnvVars(['HTTP_HOST' => 'test.de']);
41+
$url = $this->createPackage()->getUrl('test');
4142

4243
static::assertSame('http://test.de/test', $url);
43-
unset($_SERVER['HTTP_HOST']);
4444
}
4545

4646
public function testGetFromRequestStack(): void
4747
{
48-
$stack = new RequestStack();
49-
$request = new Request();
50-
$request->headers->set('HOST', 'test.de');
51-
$stack->push($request);
48+
$requestStack = new RequestStack();
49+
$requestStack->push(Request::create('https://test.de'));
5250

53-
$package = new FallbackUrlPackage([''], new EmptyVersionStrategy(), $stack);
51+
$url = $this->createPackage(requestStack: $requestStack)->getUrl('test');
5452

55-
$url = $package->getUrl('test');
53+
static::assertSame('https://test.de/test', $url);
54+
}
5655

57-
static::assertSame('http://test.de/test', $url);
56+
private function createPackage(string $url = '', ?RequestStack $requestStack = null): FallbackUrlPackage
57+
{
58+
return new FallbackUrlPackage([$url], new EmptyVersionStrategy(), $requestStack);
5859
}
5960
}

tests/unit/Core/Framework/DependencyInjection/CompilerPass/AssetBundleRegistrationCompilerPassTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ public function testCompilerPass(): void
4242

4343
$container->set('shopware.asset.asset_without_versioning', $this->createMock(Package::class));
4444

45-
/** @var Packages $assetService */
4645
$assetService = $container->get('assets.packages');
4746

4847
$assetService->getPackage('@Framework');
4948

50-
static::expectException(InvalidArgumentException::class);
49+
$this->expectException(InvalidArgumentException::class);
50+
$this->expectExceptionMessage('There is no "@FrameworkBundle" asset package.');
5151
$assetService->getPackage('@FrameworkBundle');
5252
}
5353
}

0 commit comments

Comments
 (0)