Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2ed7297

Browse filesBrowse files
committed
Add alternative convension for bundle directories
1 parent 20adf46 commit 2ed7297
Copy full SHA for 2ed7297

File tree

Expand file treeCollapse file tree

22 files changed

+250
-32
lines changed
Filter options
Expand file treeCollapse file tree

22 files changed

+250
-32
lines changed

‎UPGRADE-4.4.md

Copy file name to clipboardExpand all lines: UPGRADE-4.4.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ HttpFoundation
100100
HttpKernel
101101
----------
102102

103-
* Implementing the `BundleInterface` without implementing the `getPublicDir()` method is deprecated.
103+
* Implementing the `BundleInterface` without implementing the `getBundleDir()` method is deprecated.
104104
This method will be added to the interface in 5.0.
105105
* The `DebugHandlersListener` class has been marked as `final`
106106

‎UPGRADE-5.0.md

Copy file name to clipboardExpand all lines: UPGRADE-5.0.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ HttpFoundation
285285
HttpKernel
286286
----------
287287

288-
* The `getPublicDir()` method has been added to the `BundleInterface`.
288+
* The `getBundleDir()` method has been added to the `BundleInterface`.
289289
* Removed `Client`, use `HttpKernelBrowser` instead
290290
* The `Kernel::getRootDir()` and the `kernel.root_dir` parameter have been removed
291291
* The `KernelInterface::getName()` and the `kernel.name` parameter have been removed

‎src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php
+4-5Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
137137
$validAssetDirs = [];
138138
/** @var BundleInterface $bundle */
139139
foreach ($kernel->getBundles() as $bundle) {
140-
if (!method_exists($bundle, 'getPublicDir')) {
141-
@trigger_error(sprintf('Not defining "getPublicDir()" method in the "%s" class is deprecated since Symfony 4.4 and will not be supported in 5.0.', \get_class($bundle)), E_USER_DEPRECATED);
142-
$publicDir = 'Resources/public';
140+
if (method_exists($bundle, 'getBundleDir') && is_dir($bundle->getBundleDir().'/public')) {
141+
$originDir = $bundle->getBundleDir().'/public';
143142
} else {
144-
$publicDir = ltrim($bundle->getPublicDir(), '\\/');
143+
$originDir = $bundle->getPath().'/Resources/public';
145144
}
146-
if (!is_dir($originDir = $bundle->getPath().\DIRECTORY_SEPARATOR.$publicDir)) {
145+
if (!is_dir($originDir)) {
147146
continue;
148147
}
149148

‎src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php
+19-3Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
163163
try {
164164
$bundle = $kernel->getBundle($input->getArgument('bundle'));
165165
$transPaths = [$bundle->getPath().'/Resources/translations'];
166+
$viewsPaths = [$bundle->getPath().'/Resources/views'];
167+
if (method_exists($bundle, 'getBundleDir')) {
168+
if (is_dir($bundle->getBundleDir().'/translations')) {
169+
$transPaths = [$bundle->getBundleDir().'/translations'];
170+
}
171+
if (is_dir($bundle->getBundleDir().'/templates')) {
172+
$viewsPaths = [$bundle->getBundleDir().'/templates'];
173+
}
174+
}
166175
if ($this->defaultTransPath) {
167176
$transPaths[] = $this->defaultTransPath;
168177
}
@@ -171,7 +180,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
171180
$notice = sprintf('Storing translations files for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $dir, $bundle->getName());
172181
@trigger_error($notice.($this->defaultTransPath ? sprintf('use the "%s" directory instead.', $this->defaultTransPath) : 'configure and use "framework.translator.default_path" instead.'), E_USER_DEPRECATED);
173182
}
174-
$viewsPaths = [$bundle->getPath().'/Resources/views'];
175183
if ($this->defaultViewsPath) {
176184
$viewsPaths[] = $this->defaultViewsPath;
177185
}
@@ -206,13 +214,21 @@ protected function execute(InputInterface $input, OutputInterface $output)
206214
}
207215
} elseif ($input->getOption('all')) {
208216
foreach ($kernel->getBundles() as $bundle) {
209-
$transPaths[] = $bundle->getPath().'/Resources/translations';
217+
if (method_exists($bundle, 'getBundleDir') && is_dir($bundle->getBundleDir().'/translations')) {
218+
$transPaths[] = $bundle->getBundleDir().'/translations';
219+
} else {
220+
$transPaths[] = $bundle->getPath().'/Resources/translations';
221+
}
222+
if (method_exists($bundle, 'getBundleDir') && is_dir($bundle->getBundleDir().'/templates')) {
223+
$viewsPaths[] = $bundle->getBundleDir().'/templates';
224+
} else {
225+
$viewsPaths[] = $bundle->getPath().'/Resources/views';
226+
}
210227
if (is_dir($deprecatedPath = sprintf('%s/Resources/%s/translations', $rootDir, $bundle->getName()))) {
211228
$transPaths[] = $deprecatedPath;
212229
$notice = sprintf('Storing translations files for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $bundle->getName(), $deprecatedPath);
213230
@trigger_error($notice.($this->defaultTransPath ? sprintf('use the "%s" directory instead.', $this->defaultTransPath) : 'configure and use "framework.translator.default_path" instead.'), E_USER_DEPRECATED);
214231
}
215-
$viewsPaths[] = $bundle->getPath().'/Resources/views';
216232
if (is_dir($deprecatedPath = sprintf('%s/Resources/%s/views', $rootDir, $bundle->getName()))) {
217233
$viewsPaths[] = $deprecatedPath;
218234
$notice = sprintf('Loading Twig templates for "%s" from the "%s" directory is deprecated since Symfony 4.2, ', $bundle->getName(), $deprecatedPath);

‎src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
155155
try {
156156
$foundBundle = $kernel->getBundle($input->getArgument('bundle'));
157157
$transPaths = [$foundBundle->getPath().'/Resources/translations'];
158+
$viewsPaths = [$foundBundle->getPath().'/Resources/views'];
159+
if (method_exists($foundBundle, 'getBundleDir')) {
160+
if (is_dir($foundBundle->getBundleDir().'/translations')) {
161+
$transPaths = [$foundBundle->getBundleDir().'/translations'];
162+
}
163+
if (is_dir($foundBundle->getBundleDir().'/templates')) {
164+
$viewsPaths = [$foundBundle->getBundleDir().'/templates'];
165+
}
166+
}
158167
if ($this->defaultTransPath) {
159168
$transPaths[] = $this->defaultTransPath;
160169
}
@@ -163,7 +172,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
163172
$notice = sprintf('Storing translations files for "%s" in the "%s" directory is deprecated since Symfony 4.2, ', $foundBundle->getName(), $dir);
164173
@trigger_error($notice.($this->defaultTransPath ? sprintf('use the "%s" directory instead.', $this->defaultTransPath) : 'configure and use "framework.translator.default_path" instead.'), E_USER_DEPRECATED);
165174
}
166-
$viewsPaths = [$foundBundle->getPath().'/Resources/views'];
167175
if ($this->defaultViewsPath) {
168176
$viewsPaths[] = $this->defaultViewsPath;
169177
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+11-11Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
11431143
$defaultDir = $container->getParameterBag()->resolveValue($config['default_path']);
11441144
$rootDir = $container->getParameter('kernel.root_dir');
11451145
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
1146-
if ($container->fileExists($dir = $bundle['path'].'/Resources/translations')) {
1146+
if ((isset($bundle['dir']) && $container->fileExists($dir = $bundle['dir'].'/translations')) || $container->fileExists($dir = $bundle['path'].'/Resources/translations')) {
11471147
$dirs[] = $dir;
11481148
} else {
11491149
$nonExistingDirs[] = $dir;
@@ -1305,20 +1305,20 @@ private function registerValidatorMapping(ContainerBuilder $container, array $co
13051305
}
13061306

13071307
foreach ($container->getParameter('kernel.bundles_metadata') as $bundle) {
1308-
$dirname = $bundle['path'];
1308+
$configDir = isset($bundle['dir']) && is_dir($bundle['dir'].'/config') ? $bundle['dir'].'/config' : $bundle['path'].'/Resources/config';
13091309

13101310
if (
1311-
$container->fileExists($file = $dirname.'/Resources/config/validation.yaml', false) ||
1312-
$container->fileExists($file = $dirname.'/Resources/config/validation.yml', false)
1311+
$container->fileExists($file = $configDir.'/validation.yaml', false) ||
1312+
$container->fileExists($file = $configDir.'/validation.yml', false)
13131313
) {
13141314
$fileRecorder('yml', $file);
13151315
}
13161316

1317-
if ($container->fileExists($file = $dirname.'/Resources/config/validation.xml', false)) {
1317+
if ($container->fileExists($file = $configDir.'/validation.xml', false)) {
13181318
$fileRecorder('xml', $file);
13191319
}
13201320

1321-
if ($container->fileExists($dir = $dirname.'/Resources/config/validation', '/^$/')) {
1321+
if ($container->fileExists($dir = $configDir.'/validation', '/^$/')) {
13221322
$this->registerMappingFilesFromDir($dir, $fileRecorder);
13231323
}
13241324
}
@@ -1499,20 +1499,20 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
14991499
};
15001500

15011501
foreach ($container->getParameter('kernel.bundles_metadata') as $bundle) {
1502-
$dirname = $bundle['path'];
1502+
$configDir = isset($bundle['dir']) && is_dir($bundle['dir'].'/config') ? $bundle['dir'].'/config' : $bundle['path'].'/Resources/config';
15031503

1504-
if ($container->fileExists($file = $dirname.'/Resources/config/serialization.xml', false)) {
1504+
if ($container->fileExists($file = $configDir.'/serialization.xml', false)) {
15051505
$fileRecorder('xml', $file);
15061506
}
15071507

15081508
if (
1509-
$container->fileExists($file = $dirname.'/Resources/config/serialization.yaml', false) ||
1510-
$container->fileExists($file = $dirname.'/Resources/config/serialization.yml', false)
1509+
$container->fileExists($file = $configDir.'/serialization.yaml', false) ||
1510+
$container->fileExists($file = $configDir.'/serialization.yml', false)
15111511
) {
15121512
$fileRecorder('yml', $file);
15131513
}
15141514

1515-
if ($container->fileExists($dir = $dirname.'/Resources/config/serialization', '/^$/')) {
1515+
if ($container->fileExists($dir = $configDir.'/serialization', '/^$/')) {
15161516
$this->registerMappingFilesFromDir($dir, $fileRecorder);
15171517
}
15181518
}
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\ModernBundle\src\Entity\Person:
2+
attributes:
3+
name:
4+
serialized_name: 'full_name'
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\ModernBundle\src\Entity\Person:
2+
properties:
3+
age:
4+
- GreaterThan:
5+
value: 18

‎src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/ModernBundle/public/modern.css

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/ModernBundle/public/modern.css
Whitespace-only changes.
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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\Bundle\FrameworkBundle\Tests\Functional\Bundle\ModernBundle\src\Entity;
13+
14+
class Person
15+
{
16+
public $name;
17+
public $age;
18+
19+
public function __construct(string $name, string $age)
20+
{
21+
$this->name = $name;
22+
$this->age = $age;
23+
}
24+
}
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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\Bundle\FrameworkBundle\Tests\Functional\Bundle\ModernBundle\src;
13+
14+
use Symfony\Component\HttpKernel\Bundle\Bundle;
15+
16+
class ModernBundle extends Bundle
17+
{
18+
public function getBundleDir(): string
19+
{
20+
return \dirname($this->getPath());
21+
}
22+
}
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
OK
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ok_label: OK
+92Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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\Bundle\FrameworkBundle\Tests\Functional;
13+
14+
use Symfony\Bundle\FrameworkBundle\Command\AssetsInstallCommand;
15+
use Symfony\Bundle\FrameworkBundle\Console\Application;
16+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\ModernBundle\src\Entity\Person;
17+
use Symfony\Component\Console\Tester\CommandTester;
18+
use Symfony\Component\Filesystem\Filesystem;
19+
20+
class BundlePathsTest extends AbstractWebTestCase
21+
{
22+
public function testDefaultBundlePaths()
23+
{
24+
static::bootKernel(['test_case' => 'BundlePaths']);
25+
$bundlesMetadata = static::$container->getParameter('kernel.bundles_metadata');
26+
$bundlePath = $bundlesMetadata['FrameworkBundle']['path'];
27+
28+
$this->assertSame($bundlePath, $bundlesMetadata['FrameworkBundle']['dir']);
29+
}
30+
31+
public function testCustomBundlePaths()
32+
{
33+
static::bootKernel(['test_case' => 'BundlePaths']);
34+
$bundlesMetadata = static::$container->getParameter('kernel.bundles_metadata');
35+
$bundlePath = $bundlesMetadata['ModernBundle']['path'];
36+
37+
$this->assertSame(\dirname($bundlePath), $bundlesMetadata['ModernBundle']['dir']);
38+
}
39+
40+
public function testCustomBundlePublicPath()
41+
{
42+
$kernel = static::bootKernel(['test_case' => 'BundlePaths']);
43+
$projectDir = sys_get_temp_dir().'/'.uniqid('sf_modern', true);
44+
45+
$fs = new Filesystem();
46+
$fs->mkdir($projectDir.'/public');
47+
$command = (new Application($kernel))->add(new AssetsInstallCommand($fs, $projectDir));
48+
$commandTester = new CommandTester($command);
49+
50+
$this->assertSame(0, $commandTester->execute(['target' => $projectDir.'/public']));
51+
$this->assertFileExists($projectDir.'/public/bundles/modern/modern.css');
52+
53+
$fs->remove($projectDir);
54+
}
55+
56+
public function testCustomBundleTwigTemplatesPath()
57+
{
58+
static::bootKernel(['test_case' => 'BundlePaths']);
59+
$bundlesMetadata = static::$container->getParameter('kernel.bundles_metadata');
60+
$bundleDir = $bundlesMetadata['ModernBundle']['dir'];
61+
62+
$twig = static::$container->get('twig');
63+
$this->assertSame([$bundleDir.'/templates'], $twig->getLoader()->getPaths('Modern'));
64+
$this->assertSame("OK\n", $twig->render('@Modern/index.html.twig'));
65+
}
66+
67+
public function testCustomBundleTranslationsPath()
68+
{
69+
static::bootKernel(['test_case' => 'BundlePaths']);
70+
71+
$translator = static::$container->get('translator');
72+
$this->assertSame('OK', $translator->trans('ok_label', [], 'modern'));
73+
}
74+
75+
public function testCustomBundleValidationConfigPath()
76+
{
77+
static::bootKernel(['test_case' => 'BundlePaths']);
78+
79+
$validator = static::$container->get('validator');
80+
$this->assertTrue($validator->hasMetadataFor(Person::class));
81+
$this->assertCount(1, $constraintViolationList = $validator->validate(new Person('john', 5)));
82+
$this->assertSame('This value should be greater than 18.', $constraintViolationList->get(0)->getMessage());
83+
}
84+
85+
public function testCustomBundleSerializationConfigPath()
86+
{
87+
static::bootKernel(['test_case' => 'BundlePaths']);
88+
89+
$serializer = static::$container->get('serializer');
90+
$this->assertEquals(['full_name' => 'john', 'age' => 5], $serializer->normalize(new Person('john', 5), 'json'));
91+
}
92+
}
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
13+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\ModernBundle\src\ModernBundle;
14+
use Symfony\Bundle\TwigBundle\TwigBundle;
15+
16+
return [
17+
new FrameworkBundle(),
18+
new TwigBundle(),
19+
new ModernBundle(),
20+
];
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
imports:
2+
- { resource: ../config/default.yml }
3+
4+
framework:
5+
translator: true
6+
validation: true
7+
serializer: true
8+
9+
twig:
10+
strict_variables: '%kernel.debug%'
11+
exception_controller: ~

‎src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private function getBundleTemplatePaths(ContainerBuilder $container, array $conf
188188
}
189189
$container->addResource(new FileExistenceResource($defaultOverrideBundlePath));
190190

191-
if (file_exists($dir = $bundle['path'].'/Resources/views')) {
191+
if ((isset($bundle['dir']) && file_exists($dir = $bundle['dir'].'/templates')) || file_exists($dir = $bundle['path'].'/Resources/views')) {
192192
$bundleHierarchy[$name][] = $dir;
193193
}
194194
$container->addResource(new FileExistenceResource($dir));

‎src/Symfony/Bundle/TwigBundle/TemplateIterator.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/TemplateIterator.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,15 @@ public function getIterator()
6666
$name = substr($name, 0, -6);
6767
}
6868

69+
if (method_exists($bundle, 'getBundleDir') && is_dir($bundle->getBundleDir().'/templates')) {
70+
$bundleTemplatesDir = $bundle->getBundleDir().'/templates';
71+
} else {
72+
$bundleTemplatesDir = $bundle->getPath().'/Resources/views';
73+
}
74+
6975
$templates = array_merge(
7076
$templates,
71-
$this->findTemplatesInDirectory($bundle->getPath().'/Resources/views', $name),
77+
$this->findTemplatesInDirectory($bundleTemplatesDir, $name),
7278
$this->findTemplatesInDirectory($this->rootDir.'/Resources/'.$bundle->getName().'/views', $name)
7379
);
7480
if (null !== $this->defaultPath) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.