src/DebugTrait.php
<?php declare(strict_types=1); namespace Atk4\Core; use Psr\Log\LoggerInterface;use Psr\Log\LogLevel; trait DebugTrait{ /** @var bool Is debug enabled? */ public $debug = false; /** @var array<string, list<string>> */Property name "$_previousTrace" should not be prefixed with an underscore to indicate visibility private array $_previousTrace = []; /** * Outputs message to STDERR. */The method _echoStderr is not named in camelCase. protected function _echoStderr(string $message): void { file_put_contents('php://stderr', $message, \FILE_APPEND); } /** * Logs with an arbitrary level. * * @param LogLevel::* $level * @param string|\Stringable $message * @param array<mixed> $context */ public function log($level, $message, array $context = []): void {Avoid using static access to class 'Atk4\Core\TraitUtil' in method 'log'.
Line exceeds 120 characters; contains 124 characters if (TraitUtil::hasAppScopeTrait($this) && $this->issetApp() && $this->getApp()->logger instanceof LoggerInterface) { $this->getApp()->logger->log($level, $message, $context);The method log uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them. } else { $this->_echoStderr($message . "\n"); } } /** * Detailed debug information. * * @param bool|string|\Stringable $message * @param array<mixed> $context */ public function debug($message, array $context = []): void { // using this to switch on/off the debug for this object if (is_bool($message)) { $this->debug = $message; return; } // if debug is enabled, then log it if ($this->debug) {Avoid using static access to class 'Atk4\Core\TraitUtil' in method 'debug'.
Line exceeds 120 characters; contains 131 characters if (!TraitUtil::hasAppScopeTrait($this) || !$this->issetApp() || !$this->getApp()->logger instanceof LoggerInterface) { $message = '[' . static::class . ']: ' . $message; } $this->log(LogLevel::DEBUG, $message, $context); } } /** * Method designed to intercept one of the hardest-to-debug situations within Agile Toolkit. * * Suppose you define a hook and the hook needs to be called only once, but somehow it is * being called multiple times. You want to know where and how those calls come through. * * Place debugTraceChange inside your hook and give unique $trace identifier. If the method * is invoked through different call paths, this debug info will be logged. * * Do not use this method in production code !!! */ public function debugTraceChange(string $trace = 'default'): void {Avoid variables with short names like $bt. Configured minimum length is 3. $bt = []; foreach (debug_backtrace() as $frame) { if (isset($frame['file'])) { $bt[] = $frame['file'] . ':' . $frame['line']; } } if (isset($this->_previousTrace[$trace]) && array_diff($this->_previousTrace[$trace], $bt)) {Avoid variables with short names like $d1. Configured minimum length is 3. $d1 = array_diff($this->_previousTrace[$trace], $bt);Avoid variables with short names like $d2. Configured minimum length is 3. $d2 = array_diff($bt, $this->_previousTrace[$trace]); Line exceeds 120 characters; contains 152 characters $this->log(LogLevel::DEBUG, 'Call path for ' . $trace . ' has diverged (was ' . implode(', ', $d1) . ', now ' . implode(', ', $d2) . ")\n"); } $this->_previousTrace[$trace] = $bt; } /** * System is unusable. * * @param string|\Stringable $message * @param array<mixed> $context */ public function emergency($message, array $context = []): void { $this->log(LogLevel::EMERGENCY, $message, $context); } /** * Action must be taken immediately. * * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. * * @param string|\Stringable $message * @param array<mixed> $context */ public function alert($message, array $context = []): void { $this->log(LogLevel::ALERT, $message, $context); } /** * Critical conditions. * * Example: Application component unavailable, unexpected exception. * * @param string|\Stringable $message * @param array<mixed> $context */ public function critical($message, array $context = []): void { $this->log(LogLevel::CRITICAL, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. * * @param string|\Stringable $message * @param array<mixed> $context */ public function error($message, array $context = []): void { $this->log(LogLevel::ERROR, $message, $context); } /** * Exceptional occurrences that are not errors. * * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. * * @param string|\Stringable $message * @param array<mixed> $context */ public function warning($message, array $context = []): void { $this->log(LogLevel::WARNING, $message, $context); } /** * Normal but significant events. * * @param string|\Stringable $message * @param array<mixed> $context */ public function notice($message, array $context = []): void { $this->log(LogLevel::NOTICE, $message, $context); } /** * Interesting events. * * Example: User logs in, SQL logs. * * @param string|\Stringable $message * @param array<mixed> $context */ public function info($message, array $context = []): void { $this->log(LogLevel::INFO, $message, $context); }}