src/DebugTrait.php

Summary

Maintainability
A
0 mins
Test Coverage
<?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);
}
}