Skip to content

Commit

Permalink
Add support for Symfony 7
Browse files Browse the repository at this point in the history
  • Loading branch information
imjoehaines committed Jan 15, 2024
1 parent 6158259 commit 6eaeccd
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 163 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,16 @@ jobs:
symfony-version: '^5.0'
- php-version: '8.2'
symfony-version: '^6.0'
- php-version: '8.2'
symfony-version: '^7.0'
- php-version: '8.3'
symfony-version: '^4.4'
- php-version: '8.3'
symfony-version: '^5.0'
- php-version: '8.3'
symfony-version: '^6.0'
- php-version: '8.3'
symfony-version: '^7.0'
- php-version: '8.3'
symfony-version: 'latest'

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

## TBD

* Add support for Symfony 7
[#170](https://github.com/bugsnag/bugsnag-symfony/pull/170)

## 1.13.0 (2022-10-24)

### Enhancements
Expand Down
161 changes: 161 additions & 0 deletions DependencyInjection/BaseConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php

namespace Bugsnag\BugsnagBundle\DependencyInjection;

use Bugsnag\BugsnagBundle\EventListener\BugsnagListener;
use Bugsnag\BugsnagBundle\EventListener\BugsnagShutdown;
use Bugsnag\BugsnagBundle\Request\SymfonyResolver;
use Bugsnag\Client;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

abstract class BaseConfiguration
{
/**
* The name of the root of the configuration.
*
* @var string
*/
const ROOT_NAME = 'bugsnag';

/**
* Get the configuration tree builder.
*
* @return TreeBuilder
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder(self::ROOT_NAME);
$rootNode = $this->getRootNode($treeBuilder);

$rootNode
->children()
->scalarNode('api_key')
->defaultValue(getenv('BUGSNAG_API_KEY') ?: null)
->end()
->scalarNode('endpoint')
->defaultValue(getenv('BUGSNAG_ENDPOINT') ?: null)
->end()
->booleanNode('callbacks')
->defaultValue(true)
->end()
->booleanNode('user')
->defaultValue(true)
->end()
->scalarNode('app_type')
->defaultNull()
->end()
->scalarNode('app_version')
->defaultNull()
->end()
->booleanNode('batch_sending')
->defaultValue(true)
->end()
->scalarNode('hostname')
->defaultNull()
->end()
->booleanNode('send_code')
->defaultValue(true)
->end()
->scalarNode('release_stage')
->defaultNull()
->end()
->scalarNode('strip_path')
->defaultNull()
->end()
->scalarNode('project_root')
->defaultNull()
->end()
->booleanNode('auto_notify')
->defaultValue(true)
->end()
->scalarNode('resolver')
->defaultValue(SymfonyResolver::class)
->end()
->scalarNode('factory')
->defaultValue(ClientFactory::class)
->end()
->scalarNode('client')
->defaultValue(Client::class)
->end()
->scalarNode('listener')
->defaultValue(BugsnagListener::class)
->end()
->arrayNode('notify_release_stages')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->arrayNode('filters')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->scalarNode('shutdown')
->defaultValue(BugsnagShutdown::class)
->end()
->scalarNode('strip_path_regex')
->defaultNull()
->end()
->scalarNode('project_root_regex')
->defaultNull()
->end()
->scalarNode('guzzle')
->defaultNull()
->end()
->scalarNode('memory_limit_increase')
->defaultFalse()
->end()
->arrayNode('discard_classes')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->arrayNode('redacted_keys')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->arrayNode('feature_flags')
->prototype('array')
->children()
->scalarNode('name')
->isRequired()
->validate()
->ifTrue(function ($value) {
return !is_string($value);
})
->thenInvalid('Feature flag name should be a string, got %s')
->end()
->end()
->scalarNode('variant')->end()
->end()
->end()
->treatNullLike([])
->defaultValue([])
->end()
->scalarNode('max_breadcrumbs')
->defaultNull()
->end();

return $treeBuilder;
}

/**
* Returns the root node of TreeBuilder with backwards compatibility
* for pre-Symfony 4.1.
*
* @param TreeBuilder $treeBuilder a TreeBuilder to extract/create the root node
* from
*
* @return NodeDefinition the root node of the config
*/
protected function getRootNode(TreeBuilder $treeBuilder)
{
if (\method_exists($treeBuilder, 'getRootNode')) {
return $treeBuilder->getRootNode();
}

return $treeBuilder->root(self::ROOT_NAME);
}
}
160 changes: 4 additions & 156 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,160 +2,8 @@

namespace Bugsnag\BugsnagBundle\DependencyInjection;

use Bugsnag\BugsnagBundle\EventListener\BugsnagListener;
use Bugsnag\BugsnagBundle\EventListener\BugsnagShutdown;
use Bugsnag\BugsnagBundle\Request\SymfonyResolver;
use Bugsnag\Client;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
/**
* The name of the root of the configuration.
*
* @var string
*/
const ROOT_NAME = 'bugsnag';

/**
* Get the configuration tree builder.
*
* @return TreeBuilder
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder(self::ROOT_NAME);
$rootNode = $this->getRootNode($treeBuilder);

$rootNode
->children()
->scalarNode('api_key')
->defaultValue(getenv('BUGSNAG_API_KEY') ?: null)
->end()
->scalarNode('endpoint')
->defaultValue(getenv('BUGSNAG_ENDPOINT') ?: null)
->end()
->booleanNode('callbacks')
->defaultValue(true)
->end()
->booleanNode('user')
->defaultValue(true)
->end()
->scalarNode('app_type')
->defaultNull()
->end()
->scalarNode('app_version')
->defaultNull()
->end()
->booleanNode('batch_sending')
->defaultValue(true)
->end()
->scalarNode('hostname')
->defaultNull()
->end()
->booleanNode('send_code')
->defaultValue(true)
->end()
->scalarNode('release_stage')
->defaultNull()
->end()
->scalarNode('strip_path')
->defaultNull()
->end()
->scalarNode('project_root')
->defaultNull()
->end()
->booleanNode('auto_notify')
->defaultValue(true)
->end()
->scalarNode('resolver')
->defaultValue(SymfonyResolver::class)
->end()
->scalarNode('factory')
->defaultValue(ClientFactory::class)
->end()
->scalarNode('client')
->defaultValue(Client::class)
->end()
->scalarNode('listener')
->defaultValue(BugsnagListener::class)
->end()
->arrayNode('notify_release_stages')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->arrayNode('filters')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->scalarNode('shutdown')
->defaultValue(BugsnagShutdown::class)
->end()
->scalarNode('strip_path_regex')
->defaultNull()
->end()
->scalarNode('project_root_regex')
->defaultNull()
->end()
->scalarNode('guzzle')
->defaultNull()
->end()
->scalarNode('memory_limit_increase')
->defaultFalse()
->end()
->arrayNode('discard_classes')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->arrayNode('redacted_keys')
->prototype('scalar')->end()
->treatNullLike([])
->defaultValue([])
->end()
->arrayNode('feature_flags')
->prototype('array')
->children()
->scalarNode('name')
->isRequired()
->validate()
->ifTrue(function ($value) {
return !is_string($value);
})
->thenInvalid('Feature flag name should be a string, got %s')
->end()
->end()
->scalarNode('variant')->end()
->end()
->end()
->treatNullLike([])
->defaultValue([])
->end()
->scalarNode('max_breadcrumbs')
->defaultNull()
->end();

return $treeBuilder;
}

/**
* Returns the root node of TreeBuilder with backwards compatibility
* for pre-Symfony 4.1.
*
* @param TreeBuilder $treeBuilder a TreeBuilder to extract/create the root node
* from
*
* @return NodeDefinition the root node of the config
*/
protected function getRootNode(TreeBuilder $treeBuilder)
{
if (\method_exists($treeBuilder, 'getRootNode')) {
return $treeBuilder->getRootNode();
}

return $treeBuilder->root(self::ROOT_NAME);
}
if (PHP_MAJOR_VERSION >= 7) {
require_once __DIR__.'/configuration-with-return-type.php';
} else {
require_once __DIR__.'/configuration-without-return-type.php';
}
28 changes: 28 additions & 0 deletions DependencyInjection/configuration-with-return-type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/**
* This file declares a Configuration class with a return type on the
* 'getConfigTreeBuilder' for compatibility with Symfony 7+
*
* This is required to be in a separate file with Configuration.php requiring it
* at runtime so that we can maintain compatibility with PHP 5, where return
* types are not supported
*/

namespace Bugsnag\BugsnagBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration extends BaseConfiguration implements ConfigurationInterface
{
/**
* Get the configuration tree builder.
*
* @return TreeBuilder
*/
public function getConfigTreeBuilder(): TreeBuilder
{
return parent::getConfigTreeBuilder();
}
}
Loading

0 comments on commit 6eaeccd

Please sign in to comment.