Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.php]
indent_style = space
indent_size = 4

[*.{yaml,yml,neon}]
indent_style = space
indent_size = 4

[*.{json,js}]
indent_style = space
indent_size = 2

[Makefile]
indent_style = tab

[*.md]
trim_trailing_whitespace = false
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ on: [push]
jobs:
tests:
name: Tests
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
version: ['8.1']
version: ['8.2', '8.3', '8.4']
flags: ['', '--prefer-lowest']
fail-fast: false
steps:
- uses: actions/checkout@master
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.version }}
coverage: xdebug2
coverage: xdebug
- run: composer update --prefer-dist --no-interaction ${{ matrix.flags }}
- run: vendor/bin/atoum
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
vendor
composer.lock
/.php-cs-fixer.cache
36 changes: 36 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$finder = Finder::create()
->in(__DIR__ . '/src')
->exclude('vendor')
->name('*.php');

return (new Config())
->setRiskyAllowed(true)
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'@PHP82Migration' => true,
'@PHP80Migration:risky' => true,
'declare_strict_types' => false,
'ordered_imports' => [
'sort_algorithm' => 'alpha'
],
'no_unused_imports' => true,
'array_syntax' => ['syntax' => 'short'],
'concat_space' => ['spacing' => 'one'],
'phpdoc_order' => true,
'phpdoc_separation' => true,
'global_namespace_import' => ['import_classes' => false],
'native_function_invocation' => [
'include' => [
'@compiler_optimized'
], 'scope' => 'namespaced'
],
])
->setFinder($finder);
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.PHONY: help rector rector-dry rector-fix cs cs-fix phpstan

help:
@echo "Available commands:"
@echo " make rector-fix - Run Rector and apply changes"
@echo " make rector-dry - Run Rector in dry-run mode (no modifications)"
@echo " make cs - Run PHP CS Fixer in check mode (no modifications)"
@echo " make cs-fix - Run PHP CS Fixer and apply changes"
@echo " make phpstan - Run PHPStan static analysis"


rector: rector-dry

rector-dry:
@echo "Running Rector in dry-run mode..."
@./vendor/bin/rector process --dry-run

rector-fix:
@echo "Running Rector and applying changes..."
@./vendor/bin/rector process

cs:
@echo "Running PHP CS Fixer in check mode..."
@./vendor/bin/php-cs-fixer check --diff

cs-fix:
@echo "Running PHP CS Fixer and applying changes..."
@./vendor/bin/php-cs-fixer fix

phpstan:
@echo "Running PHPStan..."
@./vendor/bin/phpstan analyse -c phpstan.dist.neon
18 changes: 14 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,27 @@
}
],
"require": {
"php": ">=8.1",
"php": ">=8.2",
"symfony/framework-bundle": "~5.0 || ~6.0 || ~7.0",
"symfony/monolog-bundle": "~3.0",
"symfony/expression-language": "~5.0 || ~6.0 || ~7.0",
"monolog/monolog": "^3.0"
"monolog/monolog": "^3.10"
},
"require-dev": {
"atoum/atoum": "~3.4 || ~4.0",
"symfony/yaml": "~5.0 || ~6.0 || ~7.0"
"atoum/atoum": "~4.0",
"symfony/yaml": "~5.0 || ~6.0 || ~7.0",
"rector/rector": "^2.4",
"friendsofphp/php-cs-fixer": "^3.95",
"phpstan/phpstan": "^2.1",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan-symfony": "^2.0"
},
"autoload": {
"psr-0": { "": "src/" }
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
}
}
10 changes: 10 additions & 0 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
parameters:
level: 10
paths:
- src
excludePaths:
- src/M6Web/Bundle/MonologExtraBundle/Tests
symfony:
containerXmlPath: null
ignoreErrors: []
reportUnmatchedIgnoredErrors: true
23 changes: 23 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\SetList;
use Rector\ValueObject\PhpVersion;

return RectorConfig::configure()
->withPaths([
__DIR__ . '/src',
])
->withSkip([
__DIR__ . '/vendor',
])
->withPhpVersion(PhpVersion::PHP_82)
->withComposerBased(
phpunit: true,
symfony: true,
)
->withSets([
SetList::PHP_82,
]);
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
* This is the class that validates and merges configuration from your app/config files
* This is the class that validates and merges configuration from your app/config files.
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('m6_web_monolog_extra');
Expand All @@ -29,9 +26,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->variableNode('config')->end()
->end()
->validate()
->ifTrue(function ($v) {
return isset($v['handler']) && isset($v['channel']);
})
->ifTrue(static fn ($v) => is_array($v) && isset($v['handler'], $v['channel']))
->thenInvalid('You can define a channel or a handler but not both.')
->end()
->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,50 @@

namespace M6Web\Bundle\MonologExtraBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

/**
* This is the class that loads and manages your bundle configuration
* This is the class that loads and manages your bundle configuration.
*/
class M6WebMonologExtraExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('processors.yml');

$configuration = new Configuration();
/** @var array{processors: array<int|string, array{type: string, handler?: string, channel?: string, config?: mixed}>} $config */
$config = $this->processConfiguration($configuration, $configs);

if (!empty($config['processors'])) {
$alias = $this->getAlias();

foreach ($config['processors'] as $name => $processor) {
$serviceId = sprintf('%s.processor.%s', $alias, is_int($name) ? uniqid() : $name);
$serviceId = \sprintf('%s.processor.%s', $alias, \is_int($name) ? uniqid() : $name);

$tagOptions = [];
if (array_key_exists('channel', $processor)) {
if (\array_key_exists('channel', $processor)) {
$tagOptions['channel'] = $processor['channel'];
}
if (array_key_exists('handler', $processor)) {
if (\array_key_exists('handler', $processor)) {
$tagOptions['handler'] = $processor['handler'];
}

$definition = clone $container->getDefinition(sprintf('%s.processor.%s', $alias, lcfirst($processor['type'])));
$definition = clone $container->getDefinition(\sprintf('%s.processor.%s', $alias, lcfirst($processor['type'])));
$definition->setAbstract(false);
$definition->addtag('monolog.processor', $tagOptions);

if (array_key_exists('config', $processor)) {
if (\array_key_exists('config', $processor)) {
if ($definition->hasMethodCall('setConfiguration')) {
$definition->removeMethodCall('setConfiguration');
$definition->addMethodCall('setConfiguration', [$processor['config']]);
} else {
throw new InvalidConfigurationException(
sprintf('"%s" processor is not configurable.', $processor['type'])
);
throw new InvalidConfigurationException(\sprintf('"%s" processor is not configurable.', $processor['type']));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Symfony\Component\HttpKernel\Bundle\Bundle;

/**
* Bundle class
* Bundle class.
*/
class M6WebMonologExtraBundle extends Bundle
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace M6Web\Bundle\MonologExtraBundle\Processor;

use Monolog\LogRecord;
Expand All @@ -7,65 +8,49 @@

class ContextInformationProcessor
{
protected $container;
protected $expressionLanguage;
protected ContainerInterface $container;
protected ExpressionLanguage $expressionLanguage;

public function __construct(ContainerInterface $container, ExpressionLanguage $expressionLanguage)
{
$this->container = $container;
$this->expressionLanguage = $expressionLanguage;
}

/**
* Processor configuration
*
* @var array
*/
protected $configuration;
/** @var array<string, string> */
protected array $configuration;

public function __invoke(LogRecord $record): LogRecord
{
return $record->with(
context: array_merge($this->evaluateConfiguration(), $record['context'])
context: array_merge($this->evaluateConfiguration(), $record->context)
);
}

/**
* Define processor configuration
*
* @param array $config
*/
public function setConfiguration(array $config)
/** @param array<string, string> $config */
public function setConfiguration(array $config): void
{
$this->configuration = $config;
}

/**
* Evaluate configuration array
*
* @return array
*/
protected function evaluateConfiguration()
/** @return array<string, string> */
protected function evaluateConfiguration(): array
{
$context = [];
foreach ($this->configuration as $key => $value) {
$context[$key] = $this->evaluateValue($value);
}

return $context;
return array_map(fn ($value) => $this->evaluateValue($value), $this->configuration);
}

/**
* Evaluate configuration value
*
* @param string $value
*
* @return string
* Evaluate configuration value.
*/
protected function evaluateValue($value)
protected function evaluateValue(string $value): string
{
if (preg_match('/^expr\((.*)\)$/', $value, $matches)) {
return $this->expressionLanguage->evaluate($matches[1], ['container' => $this->container]);
$result = $this->expressionLanguage->evaluate($matches[1], ['container' => $this->container]);
if (!is_string($result)) {
throw new \UnexpectedValueException(\sprintf('Expression "%s" must evaluate to a string, got %s.', $matches[1], get_debug_type($result)));
}

return $result;
}

return $value;
Expand Down
Loading