Skip to content

Commit

Permalink
Added Rector to rewrite System::log to Monolog
Browse files Browse the repository at this point in the history
  • Loading branch information
aschempp committed Feb 15, 2024
1 parent 91d47d2 commit 9cf8795
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/sets/contao/contao-49.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Contao\Rector\Rector\LegacyFrameworkCallToStaticCallRector;
use Contao\Rector\Rector\LoginConstantsToSymfonySecurityRector;
use Contao\Rector\Rector\ModeConstantToScopeMatcherRector;
use Contao\Rector\Rector\SystemLogToMonologRector;
use Contao\Rector\ValueObject\ConstantToClassConstant;
use Contao\Rector\ValueObject\ConstantToServiceParameter;
use Contao\Rector\ValueObject\LegacyFrameworkCallToInstanceCall;
Expand Down Expand Up @@ -127,6 +128,7 @@
$rectorConfig->rule(LoginConstantsToSymfonySecurityRector::class);
$rectorConfig->rule(ControllerMethodToVersionsClassRector::class);
$rectorConfig->rule(ModeConstantToScopeMatcherRector::class);
$rectorConfig->rule(SystemLogToMonologRector::class);

//'Contao\Controller::getBackendLanguages()' => 'Contao\System::getContainer()->get(\'contao.intl.locales\')->getEnabledLocales(null, true)',
};
80 changes: 80 additions & 0 deletions src/Rector/SystemLogToMonologRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace Contao\Rector\Rector;

use Contao\CoreBundle\Monolog\ContaoContext;
use Contao\System;
use PhpParser\Node;
use Psr\Log\LogLevel;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

final class SystemLogToMonologRector extends AbstractLegacyFrameworkCallRector
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Rewrites deprecated System::log() calls to Monolog', [
new CodeSample(
<<<'CODE_BEFORE'
\Contao\System::log('generic log message', __METHOD__, TL_ACCESS);
\Contao\System::log('error message', __METHOD__, TL_ERROR);
CODE_BEFORE
,
<<<'CODE_AFTER'
\Contao\System::getContainer()->get('logger')->log(\Psr\Log\LogLevel::INFO, 'generic log message', ['contao' => new \Contao\CoreBundle\Monolog\ContaoContext(__METHOD__, \Contao\CoreBundle\Monolog\ContaoContext::ACCESS)]);
\Contao\System::getContainer()->get('logger')->log(\Psr\Log\LogLevel::ERROR, 'error message', ['contao' => new \Contao\CoreBundle\Monolog\ContaoContext(__METHOD__, \Contao\CoreBundle\Monolog\ContaoContext::ERROR)]);
CODE_AFTER
),
]);
}

public function refactor(Node $node): ?Node
{
assert($node instanceof Node\Expr\StaticCall || $node instanceof Node\Expr\MethodCall);

if (!$this->isParentStaticOrMethodClassCall($node, System::class, 'log')) {
return null;
}

$args = $node->getArgs();
$message = $args[0];
$method = $args[1];
$level = $args[2]->value;

if ($level instanceof Node\Expr\ConstFetch) {
$name = $this->getName($level->name);

if (\in_array($name, [
'TL_ERROR',
'TL_ACCESS',
'TL_GENERAL',
'TL_FILES',
'TL_CRON',
'TL_FORMS',
'TL_EMAIL',
'TL_CONFIGURATION',
'TL_NEWSLETTER',
'TL_REPOSITORY',
])) {
$name = substr($name, 3);
$level = new Node\Expr\ClassConstFetch(new Node\Name\FullyQualified(ContaoContext::class), $name);
}
}

$logLevel = 'INFO';
if ('Contao\CoreBundle\Monolog\ContaoContext::ERROR' === $this->getName($level) || 'ERROR' === $level->value) {
$logLevel = 'ERROR';
}

$context = new Node\Expr\New_(new Node\Name\FullyQualified(ContaoContext::class), $this->nodeFactory->createArgs([$method, $level]));
$levelConst = new Node\Expr\ClassConstFetch(new Node\Name\FullyQualified(LogLevel::class), $logLevel);

$container = new Node\Expr\StaticCall(new Node\Name\FullyQualified(System::class), 'getContainer');
$service = new Node\Expr\MethodCall($container, 'get', [new Node\Arg(new Node\Scalar\String_('monolog.logger.contao'))]);
$node = new Node\Expr\MethodCall($service, 'log', $this->nodeFactory->createArgs([$levelConst, $message, ['contao' => $context]]));

return $node;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Contao\Rector\Tests\Rector\SystemLogToMonologRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class SystemLogToMonologRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/config.php';
}
}
10 changes: 10 additions & 0 deletions tests/Rector/SystemLogToMonologRector/config/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use Contao\Rector\Rector\SystemLogToMonologRector;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(SystemLogToMonologRector::class);
};
33 changes: 33 additions & 0 deletions tests/Rector/SystemLogToMonologRector/fixture/test.php.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

use Contao\Controller;

class Foo extends Controller
{
public function bar()
{
\Contao\System::log('generic log message', __METHOD__, TL_ACCESS);
\Contao\System::log('error message', __METHOD__, TL_ERROR);
\Contao\System::log('error message', __METHOD__, 'ERROR');
\Contao\System::log('error message', 'some_method', TL_ERROR);
}
}

?>
-----
<?php

use Contao\Controller;

class Foo extends Controller
{
public function bar()
{
\Contao\System::getContainer()->get('monolog.logger.contao')->log(\Psr\Log\LogLevel::INFO, 'generic log message', ['contao' => new \Contao\CoreBundle\Monolog\ContaoContext(__METHOD__, \Contao\CoreBundle\Monolog\ContaoContext::ACCESS)]);
\Contao\System::getContainer()->get('monolog.logger.contao')->log(\Psr\Log\LogLevel::ERROR, 'error message', ['contao' => new \Contao\CoreBundle\Monolog\ContaoContext(__METHOD__, \Contao\CoreBundle\Monolog\ContaoContext::ERROR)]);
\Contao\System::getContainer()->get('monolog.logger.contao')->log(\Psr\Log\LogLevel::ERROR, 'error message', ['contao' => new \Contao\CoreBundle\Monolog\ContaoContext(__METHOD__, 'ERROR')]);
\Contao\System::getContainer()->get('monolog.logger.contao')->log(\Psr\Log\LogLevel::ERROR, 'error message', ['contao' => new \Contao\CoreBundle\Monolog\ContaoContext('some_method', \Contao\CoreBundle\Monolog\ContaoContext::ERROR)]);
}
}

?>

0 comments on commit 9cf8795

Please sign in to comment.