<?php
namespace LiaisonTrait;
trait Debug {
/**
* - Add `$lia->enableDebugging()` if I think it's a good idea.
* - make `debug` a read-only public property
* - consider just returning when debug is disabled, instead of throwing.
* - Document buffering the stack
* - Document examples of debugging
* - Document using the debugger inside an extensions, with examples
* - Review the documentation for accuracy
*
* @export(TODO.Debug)
*/
protected $debug = false;
protected $stack = [
'FUNCTIONS'=>[],
'MEDIATORS'=>[],
"STACK"=>[],
'PREFIX'=>[],
'ACTIONS'=>[],
];
protected $buffers = [];
protected $isBuffering = false;
public function debugEnabled(){
return $this->debug;
}
/**
* Substacks can help make a debug entry easier to understand. This needs better documentation
*
* @export(Usage.Debug.subStack)
*
*/
public function debug_buffer_start(){
if (!$this->debug){
throw new \Exception("Enable debugging to use debug_buffer_start() function. pass ['debug'=>true] to Liaison constructor.");
}
$this->buffers[] = 0;
$this->isBuffering = true;
}
public function debug_buffer_end(){
if (!$this->debug){
throw new \Exception("Enable debugging to use debug_buffer_end() function. pass ['debug'=>true] to Liaison constructor.");
}
$lastBufferCount = array_pop($this->buffers);
if (count($this->buffers)==0){
$this->isBuffering = false;
}
$bufferedItems = [];
while ($lastBufferCount--){
$bufferedItems[] = array_pop($this->stack[static::STACK]);
}
$bufferedItems = array_reverse($bufferedItems);
return $bufferedItems;
}
protected function debug_buffer_increment(){
$topBuffer = array_pop($this->buffers);
$topBuffer++;
$this->buffers[] = $topBuffer;
}
/**
* To enable debugging: `$lia = new \Liaison(['debug'=>true]);`
* Call `debug($debugGroup)` to get the stack of items in the debug group. Call `inspect(\Liaison::STACK)` to get a list of debugable groups currently in the stack.
*
* So far, it's \Liaison::FUNCTIONS & \Liaison::MEDIATORS, but this could change. The code will be consistent, these docs may not be.
*
* @export(Usage.Debug.debug)
*
*/
public function debug($group){
if (!$this->debug){
throw new \Exception("Enable debugging to use debug() function. pass ['debug'=>true] to Liaison constructor.");
}
if (!isset($this->stack[$group])){
throw new \Exception("Debug group '{$group}' does not exist. Liaison would need to be edited.");
}
$stack = $this->stack[static::STACK];
if ($group===static::STACK)return $stack;
$filtered = array_filter($stack,
function($item) use ($group){
if ($item['group']===$group)return true;
return false;
}
);
return $filtered;
}
/**
* To add a debug item to the stack, if `$lia->debug` is true, call `$lia->addDebug(string $debugGroup, string $action, array $extraArgs)`.
* Example:
* ```php
* if ($this->debug){
* $this->addDebug(\Liaison::FUNCTIONS, 'register', ['function'=>$functionName]);
* }
* ```
*
* @export(Usage.Debug.add)
*
*/
public function addDebug($group, $action, $args=[]){
//@TODO silently exit if debugging is disabled (no exceptions). It takes the burden off of those bits that need to be debugged.
if (!$this->debug){
return;
}
if (!isset($this->stack[$group])||$group===static::STACK){
throw new \Lia\Exception\Base("Debug group '{$group}' does not exist. Liaison would need to be edited.");
}
if ($this->isBuffering){
$this->debug_buffer_increment();
}
$trace = debug_backtrace(0,2);
$this->stack[static::STACK][] =
[
"group" => $group,
"action"=>$action,
"args" => $args,
"trace" => $trace[1]
];
}
/**
* To find out what all has been registered to liaison, call `$lia->inspect()`. With no paramaters (or an invalid paramater), you'll receive a list of items that can be inspect.
* Then call `$lia->inspect(\Liaison::THE_ITEM)` to inspect the specific thing you're interested in, such as FUNCTIONS, MEDIATORS, CONFIG, etc.
* You can also pass THE_ITEM as a string.
*
* Returned is an array w/ 'message' (string), and 'items' (array)
*
* @export(Usage.Debug.inspect)
*/
public function inspect($what=''){
switch ($what){
case static::FUNCTIONS:
$items = array_keys($this->functions);
$message = "These functions are currently registered.";
return ['message'=>$message, 'items'=>$items];
case static::MEDIATORS:
$items = array_keys($this->mediators);
$message = "These mediators are currently registered.";
return ['message'=>$message, 'items'=>$items];
case static::STACK:
$groups = [];
foreach ($this->stack[\Liaison::STACK] as $item){
$groups[$item['group']] = $item['group'];
}
sort($groups);
$message = "Use debug() to inspect the stack. These groups are currently in the stack.";
return ['message'=>$message, 'items'=>$groups];
default:
$items = (new \ReflectionClass(\Liaison::class))->getConstants();
sort($items);
return
[
'message'=>"You can pass the following Liaison class constants (except STACK) to be inspected:",
"items"=>$items
];
break;
}
}
}