8000 Merge branch '7.0' into 7.1 · jschaedl/symfony@5c847bc · GitHub
[go: up one dir, main page]

Skip to content

Commit 5c847bc

Browse files
committed
Merge branch '7.0' into 7.1
* 7.0: (26 commits) [AssetMapper] Fix: also download files referenced by url() in CSS [AssetMapper] Fix eager imports are not deduplicated [Mime] Add `TemplatedEmail::$locale` to the serialized props fix tests add return types to test fixtures fix merge [Cache] Get TRUNCATE statement from platform do not detect the deserialization_path context value twice fix detecting the database server version [Cache] Add url decoding of password in `RedisTrait` DSN [Serializer] Remove incompatible type declaration with PHP 7.2 [Serializer] Fix test Fix denormalizing empty string into object|null parameter [PropertyInfo] Fixed promoted property type detection for `PhpStanExtractor` [Serializer] Move discrimination to abstract [Serializer] Fix deserialization_path missing using contructor [Serializer] Fix access to private when Ignore [AssetMapper] Adding an option (true by default) to not publish dot files [AssetMapper] Fixing out-of-date test on Windows [HttpKernel] Fix logging deprecations to the "php" channel when channel "deprecation" is not defined ...
2 parents eba14d3 + 52feae5 commit 5c847bc

File tree

52 files changed

+905
-152
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+905
-152
lines changed

.github/workflows/integration-tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ jobs:
4848
image: redis:6.2.8
4949
ports:
5050
- 16379:6379
51+
redis-authenticated:
52+
image: redis:6.2.8
53+
ports:
54+
- 16380:6379
55+
env:
56+
REDIS_ARGS: "--requirepass p@ssword"
5157
redis-cluster:
5258
image: grokzen/redis-cluster:6.2.8
5359
ports:
@@ -170,6 +176,7 @@ jobs:
170176
run: ./phpunit --group integration -v
171177
env:
172178
REDIS_HOST: 'localhost:16379'
179+
REDIS_AUTHENTICATED_HOST: 'localhost:16380'
173180
REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005'
174181
REDIS_SENTINEL_HOSTS: 'unreachable-host:26379 localhost:26379 localhost:26379'
175182
REDIS_SENTINEL_SERVICE: redis_sentinel

src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public function markAsRendered(): void
100100
*/
101101
public function __serialize(): array
102102
{
103-
return [$this->htmlTemplate, $this->textTemplate, $this->context, parent::__serialize()];
103+
return [$this->htmlTemplate, $this->textTemplate, $this->context, parent::__serialize(), $this->locale];
104104
}
105105

106106
/**
@@ -109,6 +109,7 @@ public function __serialize(): array
109109
public function __unserialize(array $data): void
110110
{
111111
[$this->htmlTemplate, $this->textTemplate, $this->context, $parentData] = $data;
112+
$this->locale = $data[4] ?? null;
112113

113114
parent::__unserialize($parentData);
114115
}

src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@ public function testSerialize()
4343
->textTemplate('text.txt.twig')
4444
->htmlTemplate('text.html.twig')
4545
->context($context = ['a' => 'b'])
46+
->locale($locale = 'fr_FR')
4647
;
4748

4849
$email = unserialize(serialize($email));
4950
$this->assertEquals('text.txt.twig', $email->getTextTemplate());
5051
$this->assertEquals('text.html.twig', $email->getHtmlTemplate());
5152
$this->assertEquals($context, $email->getContext());
53+
$this->assertEquals($locale, $email->getLocale());
5254
}
5355

5456
public function testSymfonySerialize()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,11 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $
860860
->prototype('scalar')->end()
861861
->example(['*/assets/build/*', '*/*_.scss'])
862862
->end()
863+
// boolean called defaulting to true
864+
->booleanNode('exclude_dotfiles')
865+
->info('If true, any files starting with "." will be excluded from the asset mapper')
866+
->defaultTrue()
867+
->end()
863868
->booleanNode('server')
864869
->info('If true, a "dev server" will return the assets from the public directory (true in "debug" mode only by default)')
865870
->defaultValue($this->debug)

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,8 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13251325

13261326
$container->getDefinition('asset_mapper.repository')
13271327
->setArgument(0, $paths)
1328-
->setArgument(2, $excludedPathPatterns);
1328+
->setArgument(2, $excludedPathPatterns)
1329+
->setArgument(3, $config['exclude_dotfiles']);
13291330

13301331
$container->getDefinition('asset_mapper.public_assets_path_resolver')
13311332
->setArgument(0, $config['public_prefix']);

src/Symfony/Bundle/FrameworkBundle/Resources/config/asset_mapper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
abstract_arg('array of asset mapper paths'),
7575
param('kernel.project_dir'),
7676
abstract_arg('array of excluded path patterns'),
77+
abstract_arg('exclude dot files'),
7778
])
7879

7980
->set('asset_mapper.public_assets_path_resolver', PublicAssetsPathResolver::class)

src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
param('debug.error_handler.throw_at'),
2828
param('kernel.debug'),
2929
param('kernel.debug'),
30-
service('logger')->nullOnInvalid(),
30+
null, // Deprecation logger if different from the one above
3131
])
3232
->tag('monolog.logger', ['channel' => 'php'])
3333

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194
<xsd:element name="importmap-script-attribute" type="asset_mapper_attribute" minOccurs="0" maxOccurs="unbounded" />
195195
</xsd:sequence>
196196
<xsd:attribute name="enabled" type="xsd:boolean" />
197+
<xsd:attribute name="exclude-dotfiles" type="xsd:boolean" />
197198
<xsd:attribute name="server" type="xsd:boolean" />
198199
<xsd:attribute name="public-prefix" type="xsd:string" />
199200
<xsd:attribute name="missing-import-mode" type="missing-import-mode" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public function testAssetMapperCanBeEnabled()
137137
'importmap_polyfill' => 'es-module-shims',
138138
'vendor_dir' => '%kernel.project_dir%/assets/vendor',
139139
'importmap_script_attributes' => [],
140+
'exclude_dotfiles' => true,
140141
];
141142

142143
$this->assertEquals($defaultConfig, $config['asset_mapper']);
@@ -671,6 +672,7 @@ protected static function getBundleDefaultConfig()
671672
'importmap_polyfill' => 'es-module-shims',
672673
'vendor_dir' => '%kernel.project_dir%/assets/vendor',
673674
'importmap_script_attributes' => [],
675+
'exclude_dotfiles' => true,
674676
],
675677
'cache' => [
676678
'pools' => [],

src/Symfony/Component/AssetMapper/AssetMapperRepository.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function __construct(
3333
private readonly array $paths,
3434
private readonly string $projectRootDir,
3535
private readonly array $excludedPathPatterns = [],
36+
private readonly bool $excludeDotFiles = true,
3637
) {
3738
}
3839

@@ -185,6 +186,10 @@ private function isExcluded(string $filesystemPath): bool
185186
}
186187
}
187188

189+
if ($this->excludeDotFiles && str_starts_with(basename($filesystemPath), '.')) {
190+
return true;
191+
}
192+
188193
return false;
189194
}
190195
}

src/Symfony/Component/AssetMapper/Command/ImportMapInstallCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6464
}
6565

6666
$io->success(sprintf(
67-
'Downloaded %d asset%s into %s.',
67+
'Downloaded %d package%s into %s.',
6868
\count($downloadedPackages),
6969
1 === \count($downloadedPackages) ? '' : 's',
7070
str_replace($this->projectDir.'/', '', $this->packageDownloader->getVendorDir()),

src/Symfony/Component/AssetMapper/ImportMap/ImportMapGenerator.php

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,25 +217,36 @@ private function findAsset(string $path): ?MappedAsset
217217
return $this->assetMapper->getAssetFromSourcePath($this->importMapConfigReader->convertPathToFilesystemPath($path));
218218
}
219219

220+
/**
221+
* Finds recursively all the non-lazy modules imported by an asset.
222+
*
223+
* @return array<string> The array of deduplicated import names
224+
*/
220225
private function findEagerImports(MappedAsset $asset): array
221226
{
222227
$dependencies = [];
223-
foreach ($asset->getJavaScriptImports() as $javaScriptImport) {
224-
if ($javaScriptImport->isLazy) {
225-
continue;
226-
}
228+
$queue = [$asset];
227229

228-
$dependencies[] = $javaScriptImport->importName;
230+
while ($asset = array_shift($queue)) {
231+
foreach ($asset->getJavaScriptImports() as $javaScriptImport) {
232+
if ($javaScriptImport->isLazy) {
233+
continue;
234+
}
235+
if (isset($dependencies[$javaScriptImport->importName])) {
236+
continue;
237+
}
238+
$dependencies[$javaScriptImport->importName] = true;
229239

230-
// Follow its imports!
231-
if (!$nextAsset = $this->assetMapper->getAsset($javaScriptImport->assetLogicalPath)) {
232-
// should not happen at this point, unless something added a bogus JavaScriptImport to this asset
233-
throw new LogicException(sprintf('Cannot find imported JavaScript asset "%s" in asset mapper.', $javaScriptImport->assetLogicalPath));
240+
// Follow its imports!
241+
if (!$javaScriptAsset = $this->assetMapper->getAsset($javaScriptImport->assetLogicalPath)) {
242+
// should not happen at this point, unless something added a bogus JavaScriptImport to this asset
243+
throw new LogicException(sprintf('Cannot find JavaScript asset "%s" (imported in "%s") in asset mapper.', $javaScriptImport->assetLogicalPath, $asset->logicalPath));
244+
}
245+
$queue[] = $javaScriptAsset;
234246
}
235-
$dependencies = array_merge($dependencies, $this->findEagerImports($nextAsset));
236247
}
237248

238-
return $dependencies;
249+
return array_keys($dependencies);
239250
}
240251

241252
private function createMissingImportMapAssetException(ImportMapEntry $entry): \InvalidArgumentException

src/Symfony/Component/AssetMapper/ImportMap/RemotePackageDownloader.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public function downloadPackages(callable $progressCallback = null): array
5252
isset($installed[$entry->importName])
5353
&& $installed[$entry->importName]['version'] === $entry->version
5454
&& $this->remotePackageStorage->isDownloaded($entry)
55+
&& $this->areAllExtraFilesDownloaded($entry, $installed[$entry->importName]['extraFiles'])
5556
) {
5657
$newInstalled[$entry->importName] = $installed[$entry->importName];
5758
continue;
@@ -72,9 +73,14 @@ public function downloadPackages(callable $progressCallback = null): array
7273
}
7374

7475
$this->remotePackageStorage->save($entry, $contents[$package]['content']);
76+
foreach ($contents[$package]['extraFiles'] as $extraFilename => $extraFileContents) {
77+
$this->remotePackageStorage->saveExtraFile($entry, $extraFilename, $extraFileContents);
78+
}
79+
7580
$newInstalled[$package] = [
7681
'version' => $entry->version,
7782
'dependencies' => $contents[$package]['dependencies'] ?? [],
83+
'extraFiles' => array_keys($contents[$package]['extraFiles']),
7884
];
7985

8086
$downloadedPackages[] = $package;
@@ -109,7 +115,7 @@ public function getVendorDir(): string
109115
}
110116

111117
/**
112-
* @return array<string, array{path: string, version: string, dependencies: array<string, string>}>
118+
* @return array<string, array{path: string, version: string, dependencies: array<string, string>, extraFiles: array<string, string>}>
113119
*/
114120
private function loadInstalled(): array
115121
{
@@ -128,6 +134,10 @@ private function loadInstalled(): array
128134
if (!isset($data['dependencies'])) {
129135
throw new \LogicException(sprintf('The package "%s" is missing its dependencies.', $package));
130136
}
137+
138+
if (!isset($data['extraFiles'])) {
139+
$installed[$package]['extraFiles'] = [];
140+
}
131141
}
132142

133143
return $this->installed = $installed;
@@ -138,4 +148,15 @@ private function saveInstalled(array $installed): void
138148
$this->installed = $installed;
139149
file_put_contents($this->remotePackageStorage->getStorageDir().'/installed.php', sprintf('<?php return %s;', var_export($installed, true)));
140150
}
151+
152+
private function areAllExtraFilesDownloaded(ImportMapEntry $entry, array $extraFilenames): bool
153+
{
154+
foreach ($extraFilenames as $extraFilename) {
155+
if (!$this->remotePackageStorage->isExtraFileDownloaded($entry, $extraFilename)) {
156+
return false;
157+
}
158+
}
159+
160+
return true;
161+
}
141162
}

src/Symfony/Component/AssetMapper/ImportMap/RemotePackageStorage.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ public function isDownloaded(ImportMapEntry $entry): bool
3434
return is_file($this->getDownloadPath($entry->packageModuleSpecifier, $entry->type));
3535
}
3636

37+
public function isExtraFileDownloaded(ImportMapEntry $entry, string $extraFilename): bool
38+
{
39+
if (!$entry->isRemotePackage()) {
40+
throw new \InvalidArgumentException(sprintf('The entry "%s" is not a remote package.', $entry->importName));
41+
}
42+
43+
return is_file($this->getExtraFileDownloadPath($entry, $extraFilename));
44+
}
45+
3746
public function save(ImportMapEntry $entry, string $contents): void
3847
{
3948
if (!$entry->isRemotePackage()) {
@@ -46,6 +55,18 @@ public function save(ImportMapEntry $entry, string $contents): void
4655
file_put_contents($vendorPath, $contents);
4756
}
4857

58+
public function saveExtraFile(ImportMapEntry $entry, string $extraFilename, string $contents): void
59+
{
60+
if (!$entry->isRemotePackage()) {
61+
throw new \InvalidArgumentException(sprintf('The entry "%s" is not a remote package.', $entry->importName));
62+
}
63+
64+
$vendorPath = $this->getExtraFileDownloadPath($entry, $extraFilename);
65+
66+
@mkdir(\dirname($vendorPath), 0777, true);
67+
file_put_contents($vendorPath, $contents);
68+
}
69+
4970
/**
5071
* The local file path where a downloaded package should be stored.
5172
*/
@@ -68,4 +89,9 @@ public function getDownloadPath(string $packageModuleSpecifier, ImportMapType $i
6889

6990
return $this->vendorDir.'/'.$filename;
7091
}
92+
93+
private function getExtraFileDownloadPath(ImportMapEntry $entry, string $extraFilename): string
94+
{
95+
return $this->vendorDir.'/'.$entry->getPackageName().'/'.ltrim($extraFilename, '/');
96+
}
7197
}

0 commit comments

Comments
 (0)
0