Skip to content

Commit 236e22b

Browse files
committed
allow to configure a priority per namespace
1 parent aaa648b commit 236e22b

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 2.0.0
4+
5+
- Changed configuration format to allow setting a priority per mapping
6+
37
## 1.0.0
48

59
- Initial Version

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jms_serializer:
2828
directories:
2929
my_bundle:
3030
path: '@MyBundle/../config/serializer'
31-
namespace_prefix: 'my-bundle'
31+
namespace_prefix: 'my_bundle'
3232
app:
3333
path: '%kernel.project_dir%/config/serializer'
3434
namespace_prefix: 'app'
@@ -38,8 +38,32 @@ jms_serializer:
3838

3939
neusta_jms_serializer_extension:
4040
non_prefixed_namespaces:
41-
- 'my-bundle'
42-
- 'app'
41+
my_bundle: ~
42+
app: ~
43+
```
44+
45+
### Overriding load priority
46+
47+
It is possible to provide a `priority` per namespace. If no priority is given, `0` is assumed. When multiple configuration files for a class are found, the one with the highest priority is used.
48+
49+
For example, consider the following configuration. If a configuration file for a given class is found in both `my_bundle` and `another_bundle`, the configuration from `my_bundle` is used because it has a higher priority.
50+
51+
```yaml
52+
jms_serializer:
53+
metadata:
54+
directories:
55+
my_bundle:
56+
path: '@MyBundle/../config/serializer'
57+
namespace_prefix: 'my_bundle'
58+
another_bundle:
59+
namespace_prefix: "Company\\Thing\\CoolBundle"
60+
path: "@CompanyThingCoolBundle/../config/serializer"
61+
62+
neusta_jms_serializer_extension:
63+
non_prefixed_namespaces:
64+
my_bundle:
65+
priority: 10
66+
another_bundle: ~
4367
```
4468

4569
## Contribution

src/DependencyInjection/Configuration.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ public function getConfigTreeBuilder(): TreeBuilder
1616
->children()
1717
->arrayNode('non_prefixed_namespaces')
1818
->info('namespace names which should be ignored')
19-
->prototype('scalar')->end()
19+
->useAttributeAsKey('name')
20+
->prototype('array')
21+
->children()
22+
->scalarNode('priority')->defaultNull()->end()
23+
->end()
24+
->end()
2025
->end()
2126
->end()
2227
;

src/Serializer/FileLocator.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ public function __construct(OriginalFileLocator $fileLocator, private readonly a
1818

1919
public function findFileForClass(\ReflectionClass $class, string $extension): ?string
2020
{
21+
$possibleMatches = [];
22+
2123
foreach ($this->dirs as $prefix => $dir) {
22-
$nonPrefixed = \in_array($prefix, $this->non_prefixed_namespaces, true);
24+
$nonPrefixed = \array_key_exists($prefix, $this->non_prefixed_namespaces);
2325
if (!$nonPrefixed && !str_starts_with($class->getNamespaceName(), $prefix)) {
2426
continue;
2527
}
@@ -31,10 +33,38 @@ public function findFileForClass(\ReflectionClass $class, string $extension): ?s
3133
) . '.' . $extension;
3234

3335
if (file_exists($path)) {
34-
return $path;
36+
$possibleMatches[$prefix] = $path;
3537
}
3638
}
3739

40+
if (!empty($possibleMatches)) {
41+
$possibleMatchesSorted = $this->sortPossibleMatchesByPrefixPriority($possibleMatches);
42+
// return last one -> the highest priority
43+
end($possibleMatchesSorted);
44+
return current($possibleMatchesSorted);
45+
}
46+
3847
return null;
3948
}
49+
50+
/**
51+
* @param array<string, string> $possibleMatches prefix => file
52+
* @return array<string, string> same as input but ordered by prefix priority
53+
*/
54+
private function sortPossibleMatchesByPrefixPriority(array $possibleMatches): array
55+
{
56+
uksort($possibleMatches, function (string $prefix_a, string $prefix_b) {
57+
$getPrio = function (string $prefix): int {
58+
if (array_key_exists($prefix, $this->non_prefixed_namespaces) && array_key_exists('priority', $this->non_prefixed_namespaces[$prefix])) {
59+
return (int) $this->non_prefixed_namespaces[$prefix]['priority'];
60+
}
61+
62+
return 0;
63+
};
64+
65+
return $getPrio($prefix_a) <=> $getPrio($prefix_b);
66+
});
67+
68+
return $possibleMatches;
69+
}
4070
}

0 commit comments

Comments
 (0)