You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

189 lines
7.0 KiB

<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
/**
* \brief Tiki internal debugger
* \author zaufi <zaufi@sendmail.ru>
*/
require_once('lib/debug/debugger-common.php');
/// Path to debugger's external commands
define('DBG_PLUGINS_DIR', 'lib/debug');
/**
* \brief Class to manage debugger
*/
class Debugger extends ResultType
{
/// Array of found command providers
public $commands;
///Index of interface extension found as external debugger command
public $noname_cmd_idx;
/// Array of user logged messages. Elements are stored with keys 'timestamp' and 'msg'
public $dmsgs;
/// Constructor
public function __construct()
{
// Call base constructor
parent::__construct();
// Init data members
$this->noname_cmd_idx = 0;
$this->dmsgs = [];
// build array of available commands
$this->rescan_for_commands();
}
/// Rebuild commands list
public function rescan_for_commands()
{
$files = [];
if (is_dir(DBG_PLUGINS_DIR)) {
if ($dh = opendir(DBG_PLUGINS_DIR)) {
while (($file = readdir($dh)) !== false) {
if (preg_match("/^debug-command_.*\.php$/", $file)) {
array_push($files, $file);
}
}
closedir($dh);
}
}
// Refresh object in commands array
$this->commands = [];
foreach ($files as $file) {
include_once(DBG_PLUGINS_DIR . '/' . $file);
$func_name = preg_replace(",debug-command_([A-Za-z0-9]+)\.php,", "dbg_command_factory_\\1", $file);
if (function_exists($func_name)) {
$obj = $func_name();
if (is_subclass_of($obj, "DebuggerCommand")) {
// If command have name, insert in by name, else assume that
// it is interface only extension
if (strlen($obj->name()) > 0) {
$this->commands[$obj->name()] = $obj;
} else {
$this->commands[$this->noname_cmd_idx++] = $obj;
}
}
// else
// TODO: Must issue a warnig?
}
// Must issue a warning?
}
}
/// Handle user typed command
public function execute($rawcmd)
{
$this->reset();
$rawcmd = trim($rawcmd);
$result = '';
// Is smth else in command line 'cept spaces?
if (strlen($rawcmd)) {
// Extract first word (possible the only) from command line...
$cmd = substr($rawcmd, 0, (($pos = strpos($rawcmd, ' ')) == false ? strlen($rawcmd) : $pos));
// Check for the only internal command: help :)
if (strcmp($cmd, 'help') !== 0) {
// No this is smth other... Is assiciated handler present?
if (isset($this->commands[$cmd])) {
// OK. May call external command...
$result = $this->commands[$cmd]->execute(str_replace($cmd, '', $rawcmd));
$this->set_result_type($this->commands[$cmd]->result_type());
if ($this->result_type() == TPL_RESULT) {
$this->set_result_tpl($this->commands[$cmd]->result_tpl());
}
} else {
// Command not found... Issue a spam!
$result = '<span class="dbgerror">No such command "' . $cmd . '"</span>';
$this->set_result_type(HTML_RESULT);
}
} else {
// Handle help command. Is help for some command needed?
$rawcmd = trim(str_replace($cmd, "", $rawcmd));
$result = [];
$result["action"] = 'none';
if (strlen($rawcmd) == 0) {
$result["action"] = 'list';
// No. This is along help on command line. Append my help...
$result[0][] = ['cmd' => 'help',
'description' => 'Display list of commands or help for specified command (<code>help print</code> for example)'];
foreach ($this->commands as $cmdobj) {
if (strlen(trim($cmdobj->name())) > 0) {
$result[0][] = ['cmd' => $cmdobj->name(), 'description' => $cmdobj->description()];
}
}
} else {
// What command help requested for??
if (isset($this->commands[$rawcmd])) {
$result["action"] = 'one';
$cmdobj = $this->commands[$rawcmd];
$result['name'] = $cmdobj->name();
$result['description'] = $cmdobj->description();
$result['syntax'] = $cmdobj->syntax();
$result['example'] = $cmdobj->example();
} else {
$this->set_result_type(HTML_RESULT);
return '<tr><td><span class="dbgerror">No such command "' . $rawcmd . '"</span></td></tr>';
}
}
$this->set_result_type(TPL_RESULT);
$this->set_result_tpl('debug/tiki-debug_console_help.tpl');
}
}
return $result;
}
/// Request from interface module to draw plugable parts...
public function background_tabs_draw()
{
$result = [];
foreach ($this->commands as $cmd) {
if ($cmd->have_interface()) {
$result[$cmd->caption()] = $cmd->draw_interface();
}
}
return $result;
}
/// Store user messages...
public function msg($s)
{
$this->dmsgs[] = ["timestamp" => time(), "msg" => $s];
}
/**
* \brief Dump variable (global) into string (errors aware function)
* \todo Need to rename all local variables to smth realy unique
* (smth that user never guess and try to print :)
*/
public function str_var_dump($v)
{
$result = '';
$v = trim($v);
if (strlen(str_replace("$", "", $v)) > 0) {
// Need to make var global... strip [] if needed
$global = (($pos = strpos($v, '[')) == false) ? $v : substr($v, 0, $pos);
//
$expr = "global $global;\n\$result .= print_r($v, true);";
$php_errormsg = '';
@eval($expr);
if (strlen($php_errormsg)) {
$result .= "ERROR: " . $php_errormsg;
}
}
return $result;
}
public function var_dump($v)
{
$this->dmsgs[] = ["timestamp" => time(), "msg" => $this->str_var_dump($v)];
}
}
global $debugger;
$debugger = new Debugger();
// First message (will not appear if no user messages wil be added)
$debugger->msg("Debugger startup OK. " . count($debugger->commands) . " plugable commands found");