<?php
/**
*
* @author Benjamin Gillissen <hide@address.com>
*
* **************************************************************
Copyright (C) 2009 Benjamin Gillissen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details at:
http://www.gnu.org/copyleft/gpl.html
* **************************************************************
*/
/* allow client to configure the display of the request debug
* on the profile page.
* fetch ?
* * debug container blockvis open by default ?
* * use color ?
* * level, file, context mask ?, later (some js)
* * max events (drop first) ?
* * backtrace ?
* * * backtrace blockvis open by default ?
*/
class tfeat_debug {
const PROFILE = TRUE;
private static $init=FALSE;
private static $CC;
private static function init(){
if ( ! isset(self::$CC) ){
$run = Array(client_configs::SESSION=>'profile');
$store = Array(client_configs::PROFILE=>'site_profile');
$run_update = Array(client_configs::POST=>'');
$store_update= Array(client_configs::POST=>'');
self::$CC = new client_configs($run, $store, $run_update, $store_update);
unset($run, $store, $run_update, $store_update);
if ( isset($_POST['tfeat_debug']) ){
$t = Array('fetch', 'color', 'ajax', 'backtrace');
foreach($t as $k => &$var){
if ( !isset($_POST['debug_'.$var]) ){ $_POST['debug_'.$var] = 0; }
}
}
}
}
public static function implent(){
//called by thm_helper __construct
//so here i can add needed css, js to theyr queue before header is sent
//if ( FALSE != self::get_client_conf('fetch') ){
thm_mediaq::append_css_file('debug');
thm_mediaq::append_js_file('switch_debug');
thm_mediaq::append_js_file('swap_blockvis');
//}
self::$init=TRUE;
return TRUE;
}
public static function genform(){
//called by profile page template,
$o['fetch'] = self::get_client_conf('fetch');
if ( FALSE == $o['fetch'] ){ return $o; }
$o['color'] = self::get_client_conf('color');
$o['ajax'] = self::get_client_conf('ajax');
$o['backtrace'] = self::get_client_conf('backtrace');
if ( FALSE == $o['backtrace'] ){ return $o; }
$o['backvis'] = self::get_client_conf('backvis');
return $o;
}
public static function genpart($part, $of=FALSE){
if ( !self::$init ){ errors::raise('Debug TFeat must be implented, add it to the first param of the thm_helper construct method !', CORE_LOG_ERROR, 'TPL'); }
if ( FALSE == self::get_client_conf('fetch') ){ return; }
//called by parser, with block like {--TFEAT=debug; $part --}
//2 parts for a debug feature :
if ( $part == 'button' ){
//- show|hidde button => {--TFEAT=debug;button--} in header
$o = '<div class="debugbutton" onclick="javascript:swap_blockvis(0, \'block_debug\', \'debug_content_\');" title="Click to swap debug display status">[±]</div>';
if ( !$of ){ return $o; }
call_user_func($of, $o);
} elseif ( $part == 'events' ){
//- container + events => {--TFEAT=debug;events--}, in footer, drop failure when called with $of=false
if ( !$of ){
error::raise('Debug Theme feature must be parsed with direct output !', CORE_LOG_ERROR, 'TPL');
return '';
}
$o = '<div class="debug_container">
<div id="block_debug" class="debug_content_close">
<div id="switch_debug" class="event_header">[ <a href="javascript:switch_debug(\'main\')" >Main</a> ]</div>
<div id="showed_debug"></div>
<div id="debug_main" class="hidden_debug">
<div class="event_header">
<b>'.langs::dico_translate('req_time', NULL, 'debug').' :</b><br/>';
call_user_func($of, $o);
$reqtimes = chrono::stopall();
$tot = $reqtimes[count($reqtimes)-1]['time'];
foreach($reqtimes as $k => $time){
if ( $k !== count($reqtimes)-1 ){
$prct = CORE::ToPercent($time['time'], $tot, 1);
$o = $time['ref'].' : '.$time['time'].' s<br/>';
$o .= '<div style="width:50%;border:1px solid black">
<div style="width:'.$prct.'%;background-color:gray;height:5px"></div>
</div>';
call_user_func($of, $o);
}
/*
$isfirst = ($k == 0);
$o='';
if ( $islast ){ $o = ' = '; } elseif (!$isfirst) { $o = ' + '; }
$o .= '<span id="time_'.$time['ref'].'" title="'.$time['ref'].'">'.$time['ref'].'='.$time['time'].'</span> s';
*/
}
//call_user_func($of, $o);
$o = 'total : '.$tot.' s<br/>';
unset($tot, $reqtimes);
if ( function_exists('memory_get_peak_usage') ){
$o .= '<b>'.langs::dico_translate('mempeak', NULL, 'debug').' :</b> '.langs::number(floor(memory_get_peak_usage()/1024/1024), 1).'MB<br/>';
}
$o .= '<b>'.langs::dico_translate('memlimit', NULL, 'debug').' :</b> '.ini_get('memory_limit');
$o .= "
</div>";
call_user_func($of, $o);
unset($o);
$backtrace = self::get_client_conf('backtrace');
$backvis = self::get_client_conf('backvis');
$color = self::get_client_conf('color');
while( $event = errors::fetch_debugchan($backtrace, $color) ){
$id = CORE::hash(NULL, 5);
$o = '
<div class="event_container">
<div class="event_header">';
if ( is_array($event) ){
if ( FALSE != $backtrace ){
$o .='<span class="blockvis" style="cursor:pointer" onclick="javascript:swap_blockvis(0, \'event_'.$id.'\', \'event_content_\');">[±]</span> ';
}
$o .= $event['event']."</div>\n";
if ( FALSE != $backtrace AND isset($event['backtrace']) ){
if ( FALSE != $backvis ){ $dft = 'open'; } else { $dft = 'close'; }
$o .= '<div id="event_'.$id.'" class="event_content_'.$dft.'">bcktrace :<br />'.$event['backtrace'].'</div>';
}
} else {
$o .= $event."</div>\n";
}
$o .= ' </div>';
call_user_func($of, $o);
unset($o, $event, $id);
}
$o = '
<div style="height:5px"></div>
<div onclick="javascript:swap_blockvis(0, \'block_debug\', \'debug_content_\');" title="Click to swap debug display status">[-]</div>
</div>
</div>
</div>';
call_user_func($of, $o);
}
return TRUE;
}
public static function get_client_conf($k){
self::init();
$k = 'debug_'.$k;
if ( self::$CC->is_updated($k) ){
$new = self::$CC->get_updated($k);
self::$CC->store_updated($k);
self::$CC->del_updated($k);
} elseif ( self::$CC->is_stored($k) ){ //check storage
$new = self::$CC->get_stored($k);
} elseif ( $k === 'debug_fetch' OR $k === 'debug_color'){ //not defined nor updated so default to fetch and color
$new=1;
}
if ( isset($new) ){
if ( $new != 1 ){ $new = FALSE; } else { $new = TRUE; }
return $new;
}
return FALSE;
}
}
return TRUE;