Skip to content

Commit e187c68

Browse files
authored
feat(upgrade): use multiple routes (#70)
* feat(upgrade): use multiple routes * feat(upgrade): re add route param as deprecated
1 parent c406a5b commit e187c68

16 files changed

Lines changed: 402 additions & 69 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,34 @@ m6_web_log_bridge:
4545
filters:
4646
get_article_error:
4747
route: get_article
48+
routes: ['get_article']
4849
method: ['GET']
4950
status: [422, 500]
5051
level: 'error'
5152
options:
5253
response_body: true # from add Response body content (with DefaultFormatter)
5354
post_article_all:
5455
route: post_article
56+
routes: ['post_article']
5557
method: ~ # from all methods
5658
status: ~ # from all status
5759
get_article_not_found:
5860
route: get_article
61+
routes: ['get_article']
5962
method: ['GET']
6063
status: [404]
6164
level: 'warning'
6265
edit_category:
6366
route: get_category
67+
routes: ['get_category']
6468
method: ['POST', 'PUT']
6569
status: [400-422, ^510, !530-550]
6670
level: 'error'
6771
options:
6872
post_parameters: true # From add post parameters in response content (with DefaultFormatter)
6973
all_error: # All route, all method in error
7074
route: ~
75+
routes: ~
7176
method: ~
7277
status: [31*, 4*, 5*]
7378
level: 'critical'
@@ -79,6 +84,13 @@ m6_web_log_bridge:
7984
channel: my_channel_to_log # monolog channel, optional, default 'log_bridge'
8085
```
8186
87+
Routes support multiples formats :
88+
```yaml
89+
routes: ['my_route'] # Add only this route
90+
routes: ['my_route', 'another_route'] # Add multiples routes
91+
routes: ['!excluded_one', '!excluded_two'] # Add all routes except the excluded
92+
```
93+
8294
*By default, `level` is `info`*
8395

8496
You can declare all the options you want.

src/M6Web/Bundle/LogBridgeBundle/Config/Filter.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class Filter
1111
{
1212
private ?string $route = null;
1313

14+
private ?array $routes = [];
15+
1416
/** @var string[]|null */
1517
private ?array $method = null;
1618

@@ -43,6 +45,18 @@ public function getRoute(): ?string
4345
return $this->route;
4446
}
4547

48+
public function setRoutes(?array $routes): self
49+
{
50+
$this->routes = $routes;
51+
52+
return $this;
53+
}
54+
55+
public function getRoutes(): ?array
56+
{
57+
return $this->routes;
58+
}
59+
4660
/**
4761
* @param string[]|null $method
4862
*/

src/M6Web/Bundle/LogBridgeBundle/Config/FilterParser.php

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,17 @@ protected function isRoute(string $name): bool
4747
return $this->router?->getRouteCollection()->get($name) !== null;
4848
}
4949

50+
protected function getAllRoutes(): array
51+
{
52+
$routesCollection = $this->router?->getRouteCollection()->all();
53+
54+
return array_keys($routesCollection);
55+
}
56+
5057
/**
5158
* @param array{
5259
* route?: string,
60+
* routes?: string[],
5361
* method?: string[],
5462
* status?: int[],
5563
* level?: string,
@@ -59,11 +67,15 @@ protected function isRoute(string $name): bool
5967
public function parse(string $name, array $config): Filter
6068
{
6169
if (
62-
!array_key_exists('route', $config) ||
70+
(!array_key_exists('route', $config) && !array_key_exists('routes', $config)) ||
6371
!array_key_exists('method', $config) ||
6472
!array_key_exists('status', $config)
6573
) {
66-
throw new ParseException(sprintf('Undefined "route", "method" or "status" parameter from filter "%s"', $name));
74+
throw new ParseException(sprintf('Undefined "route(s)", "method" or "status" parameter from filter "%s"', $name));
75+
}
76+
77+
if (array_key_exists('route', $config) && array_key_exists('routes', $config)) {
78+
throw new ParseException(sprintf('You can\'t use both "route" and "routes" parameter from filter "%s"', $name));
6779
}
6880

6981
if (!array_key_exists('level', $config)) {
@@ -74,7 +86,14 @@ public function parse(string $name, array $config): Filter
7486
->setMethod($config['method'])
7587
->setStatus($config['status']);
7688

77-
$this->parseRoute($filter, $config['route']);
89+
if (array_key_exists('route', $config)) {
90+
$this->parseRoute($filter, $config['route']);
91+
}
92+
93+
if (array_key_exists('routes', $config)) {
94+
$this->parseRoutes($filter, $config['routes'] ?? []);
95+
}
96+
7897
$this->parseLevel($filter, $config['level']);
7998

8099
return $filter->setOptions($config['options'] ?? []);
@@ -89,6 +108,42 @@ protected function parseRoute(Filter $filter, ?string $route): void
89108
$filter->setRoute($route);
90109
}
91110

111+
protected function parseRoutes(Filter $filter, ?array $routes): void
112+
{
113+
if (empty($routes)) {
114+
$filter->setRoutes(['all']);
115+
116+
return;
117+
}
118+
119+
// Find and keep excluded routes
120+
$excludedRoutes = array_filter($routes, function (string $route) {
121+
return str_starts_with($route, '!');
122+
});
123+
124+
// Create an array with routes not excluded
125+
$routes = array_diff_key($routes, $excludedRoutes);
126+
127+
// Check that the route's name exist
128+
foreach ($routes as $route) {
129+
if (!$this->isRoute($route)) {
130+
throw new ParseException(sprintf('Undefined route "%s" from router service', $route));
131+
}
132+
}
133+
134+
// If empty routes, return all routes except the excluded ones
135+
if (empty($routes)) {
136+
$existingRoutes = $this->getAllRoutes();
137+
$excludedRoutes = array_map(function (string $route) {
138+
return ltrim($route, '!');
139+
}, $excludedRoutes);
140+
141+
$routes = array_values(array_diff($existingRoutes, $excludedRoutes));
142+
}
143+
144+
$filter->setRoutes($routes);
145+
}
146+
92147
protected function parseLevel(Filter $filter, ?string $level): void
93148
{
94149
if (!in_array($level, $this->allowedLevels, true)) {

src/M6Web/Bundle/LogBridgeBundle/Config/Parser.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public function __construct(private RouterInterface $router)
2020
/**
2121
* @param array<string, array{
2222
* route?: string,
23+
* routes?: string[],
2324
* method?: string[],
2425
* status?: int[],
2526
* level?: string,
@@ -43,6 +44,7 @@ protected function createFilterCollection(array $filters): FilterCollection
4344
* @param array{
4445
* filters?: array<string, array{
4546
* route?: string,
47+
* routes?: string[],
4648
* method?: string[],
4749
* status?: int[],
4850
* level?: string,

src/M6Web/Bundle/LogBridgeBundle/DependencyInjection/Configuration.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,17 @@ public function getConfigTreeBuilder(): TreeBuilder
5353
->useAttributeAsKey('name')
5454
->prototype('array')
5555
->children()
56-
->scalarNode('route')->defaultNull()->end()
56+
->scalarNode('route')
57+
->defaultNull()
58+
->setDeprecated(
59+
'm6web/log-bridge-bundle',
60+
'10.1',
61+
'The "route" option is deprecated. Use "routes" instead.'
62+
)
63+
->end()
64+
->arrayNode('routes')
65+
->prototype('scalar')->end()
66+
->end()
5767
->arrayNode('method')
5868
->prototype('scalar')->end()
5969
->end()

src/M6Web/Bundle/LogBridgeBundle/Formatter/FormatterInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function getLogContent(Request $request, Response $response, array $optio
2020
/**
2121
* @param array<string, bool|string> $options
2222
*
23-
* @return array<string, string|int>
23+
* @return array<string, array|int|string>
2424
*/
2525
public function getLogContext(Request $request, Response $response, array $options): array;
2626
}

src/M6Web/Bundle/LogBridgeBundle/Matcher/BuilderInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface BuilderInterface
1414
/**
1515
* @param array<string, array{
1616
* route?: string,
17+
* routes?: string[],
1718
* method?: string[],
1819
* status?: int[],
1920
* level?: string,

src/M6Web/Bundle/LogBridgeBundle/Matcher/Dumper/PhpMatcherDumper.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,25 @@ private function compileFilter(Filter $filter): array
258258
{
259259
$compiledKeys = [];
260260
$compiled = [];
261+
/** @var array $routesPrefix */
262+
$routesPrefix = $filter->getRoutes();
261263
/** @var string $prefix */
262264
$prefix = is_null($filter->getRoute()) ? 'all' : $filter->getRoute();
263265

266+
$compiledKeys = isset($routesPrefix) ?
267+
$this->compileFilterRoutes($filter, $routesPrefix, $compiledKeys) :
268+
$this->compileFilterRoute($filter, $prefix, $compiledKeys);
269+
270+
foreach ($compiledKeys as $key) {
271+
$compiled[$key]['options'] = $filter->getOptions();
272+
$compiled[$key]['level'] = $filter->getLevel();
273+
}
274+
275+
return $compiled;
276+
}
277+
278+
private function compileFilterRoute(Filter $filter, string $prefix, array $compiledKeys): array
279+
{
264280
if (empty($filter->getMethod())) {
265281
$prefix = sprintf('%s.all', $prefix);
266282
$compiledKeys = $this->compileFilterStatus($prefix, $filter);
@@ -271,18 +287,34 @@ private function compileFilter(Filter $filter): array
271287
}
272288
}
273289

274-
foreach ($compiledKeys as $key) {
275-
$compiled[$key]['options'] = $filter->getOptions();
276-
$compiled[$key]['level'] = $filter->getLevel();
290+
return $compiledKeys;
291+
}
292+
293+
private function compileFilterRoutes(Filter $filter, ?array $routesPrefix, array $compiledKeys): array
294+
{
295+
if (empty($filter->getMethod())) {
296+
foreach ($routesPrefix as $routePrefix) {
297+
$prefix = sprintf('%s.all', $routePrefix);
298+
$compiledKeys = array_merge($compiledKeys, $this->compileFilterStatus($prefix, $filter));
299+
}
300+
301+
return $compiledKeys;
277302
}
278303

279-
return $compiled;
304+
foreach ($filter->getMethod() as $method) {
305+
foreach ($routesPrefix as $routePrefix) {
306+
$methodPrefix = sprintf('%s.%s', $routePrefix, $method);
307+
$compiledKeys = array_merge($compiledKeys, $this->compileFilterStatus($methodPrefix, $filter));
308+
}
309+
}
310+
311+
return $compiledKeys;
280312
}
281313

282314
/**
283315
* @return string[]
284316
*/
285-
private function compileFilterStatus(string $prefix, Filter $filter): array
317+
private function compileFilterStatus(?string $prefix, Filter $filter): array
286318
{
287319
$compiled = [];
288320
/** @var string[]|null $filterStatusList */

src/M6Web/Bundle/LogBridgeBundle/Tests/Fixtures/Resources/config/config.yml

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,49 @@ active_filters:
66

77
filters:
88
get_clip_all_status:
9-
route: get_clip
9+
routes: ['get_clip']
1010
method: ['GET', 'PUT']
1111
status: ~
1212
options:
1313
response_body: true
1414
post_parameters: true
1515

1616
put_clip_form_all_200:
17-
route: put_clips_form
17+
routes: ['put_clips_form']
1818
method: ['PUT']
1919
status: [!^240, 2*]
2020

2121
delete_clip_500_all_hundred_without_580_to_590:
22-
route: delete_clip
22+
routes: ['delete_clip']
2323
method: ['DELETE']
2424
status: [5*, !58*]
2525

2626
edit_clip_5*_30*_without_550_549:
27-
route: edit_clip
27+
routes: ['edit_clip']
2828
method: ['PATH']
2929
status: [5*, !550, !549, 30*]
3030

3131
edit_clip_404_to_410:
32-
route: edit_clip
32+
routes: ['edit_clip']
3333
method: ['POST']
3434
status: [404-410]
3535

3636
delete_clip_450_more_without_452_to_458:
37-
route: delete_clip
37+
routes: ['delete_clip']
3838
method: ['DELETE']
3939
status: [^450, !452-458]
4040

4141
get_program_200_hundred_without_290_more:
42-
route: get_program
42+
routes: ['get_program']
4343
method: ['GET']
44-
status: [2*, !^290]
44+
status: [2*, !^290]
45+
46+
get_program_200_hundred_without_route_no_filter:
47+
routes: [ 'get_program', '!no_filter' ]
48+
method: [ 'GET' ]
49+
status: [ 2*, !^290 ]
50+
51+
get_program_200_hundred_with_simple_route:
52+
route: 'get_program'
53+
method: [ 'GET' ]
54+
status: [ 2*, !^290 ]

src/M6Web/Bundle/LogBridgeBundle/Tests/Units/BaseTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ protected function getMockedRouterCollection(): object
1515
{
1616
$collection = new \mock\Symfony\Component\Routing\RouteCollection();
1717
$collection->getMockController()->get = fn($name) => $name != 'invalid_route' ? new Route('/path') : null;
18+
$collection->getMockController()->all = [
19+
'fake_url' => new Route('/fake_url'),
20+
'fake_second_url' => new Route('/fake_second_url'),
21+
'excluded_route' => new Route('/excluded_route')
22+
];
1823

1924
return $collection;
2025
}

0 commit comments

Comments
 (0)