2008-05-30 11:40:08 +00:00
< ? php
/**
* Framework debugging and PHP error - handling class
*
* Provides enhanced logging , stack traces , and rendering debug views
*
2010-10-03 16:38:58 +00:00
* PHP 5
2008-05-30 11:40:08 +00:00
*
2009-05-01 21:05:46 +00:00
* CakePHP ( tm ) : Rapid Development Framework ( http :// cakephp . org )
2011-05-29 21:31:39 +00:00
* Copyright 2005 - 2011 , Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2008-05-30 11:40:08 +00:00
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
*
2011-05-29 21:31:39 +00:00
* @ copyright Copyright 2005 - 2011 , Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2010-01-26 22:03:03 +00:00
* @ link http :// cakephp . org CakePHP ( tm ) Project
2011-07-26 06:16:14 +00:00
* @ package Cake . Utility
2008-10-30 17:30:26 +00:00
* @ since CakePHP ( tm ) v 1.2 . 4560
2009-05-01 21:05:46 +00:00
* @ license MIT License ( http :// www . opensource . org / licenses / mit - license . php )
2008-05-30 11:40:08 +00:00
*/
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
* Included libraries .
*
*/
2010-12-04 07:04:30 +00:00
App :: uses ( 'CakeLog' , 'Log' );
App :: uses ( 'String' , 'Utility' );
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
* Provide custom logging and error handling .
*
* Debugger overrides PHP ' s default error handling to provide stack traces and enhanced logging
*
2011-07-26 06:16:14 +00:00
* @ package Cake . Utility
2010-03-28 15:34:58 +00:00
* @ link http :// book . cakephp . org / view / 1191 / Using - the - Debugger - Class
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
class Debugger {
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* A list of errors generated by the application .
2008-05-30 11:40:08 +00:00
*
* @ var array
* @ access public
*/
2010-04-04 07:14:00 +00:00
public $errors = array ();
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Contains the base URL for error code documentation .
2008-05-30 11:40:08 +00:00
*
* @ var string
* @ access public
*/
2010-04-04 07:14:00 +00:00
public $helpPath = null ;
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* The current output format .
2008-05-30 11:40:08 +00:00
*
* @ var string
2008-12-07 20:44:00 +00:00
* @ access protected
2008-05-30 11:40:08 +00:00
*/
2010-04-04 06:36:12 +00:00
protected $_outputFormat = 'js' ;
2009-05-01 21:05:46 +00:00
/**
* Templates used when generating trace or error strings . Can be global or indexed by the format
* value used in $_outputFormat .
*
* @ var string
* @ access protected
*/
2010-04-04 06:36:12 +00:00
protected $_templates = array (
2009-05-01 21:05:46 +00:00
'log' => array (
'trace' => '{:reference} - {:path}, line {:line}' ,
'error' => " { :error} ( { :code}): { :description} in [ { :file}, line { :line}] "
),
'js' => array (
'error' => '' ,
'info' => '' ,
'trace' => '<pre class="stack-trace">{:trace}</pre>' ,
'code' => '' ,
'context' => '' ,
'links' => array ()
),
'html' => array (
'trace' => '<pre class="cake-debug trace"><b>Trace</b> <p>{:trace}</p></pre>' ,
'context' => '<pre class="cake-debug context"><b>Context</b> <p>{:context}</p></pre>'
),
'txt' => array (
'error' => " { :error}: { :code} :: { :description} on line { :line} of { :path} \n { :info} " ,
'context' => " Context: \n { :context} \n " ,
'trace' => " Trace: \n { :trace} \n " ,
'code' => '' ,
'info' => ''
),
'base' => array (
'traceLine' => '{:reference} - {:path}, line {:line}'
)
);
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Holds current output data when outputFormat is false .
2008-05-30 11:40:08 +00:00
*
* @ var string
*/
2010-04-04 06:36:12 +00:00
protected $_data = array ();
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Constructor .
2008-05-30 11:40:08 +00:00
*
*/
2011-05-28 20:38:46 +00:00
public function __construct () {
2008-05-30 11:40:08 +00:00
$docRef = ini_get ( 'docref_root' );
2009-05-01 21:05:46 +00:00
2010-10-19 20:46:17 +00:00
if ( empty ( $docRef ) && function_exists ( 'ini_set' )) {
2008-05-30 11:40:08 +00:00
ini_set ( 'docref_root' , 'http://php.net/' );
}
if ( ! defined ( 'E_RECOVERABLE_ERROR' )) {
define ( 'E_RECOVERABLE_ERROR' , 4096 );
}
2009-05-01 21:05:46 +00:00
if ( ! defined ( 'E_DEPRECATED' )) {
define ( 'E_DEPRECATED' , 8192 );
}
2009-07-25 17:27:17 +00:00
$e = '<pre class="cake-debug">' ;
$e .= '<a href="javascript:void(0);" onclick="document.getElementById(\'{:id}-trace\')' ;
2009-05-01 21:05:46 +00:00
$e .= '.style.display = (document.getElementById(\'{:id}-trace\').style.display == ' ;
$e .= '\'none\' ? \'\' : \'none\');"><b>{:error}</b> ({:code})</a>: {:description} ' ;
$e .= '[<b>{:path}</b>, line <b>{:line}</b>]' ;
$e .= '<div id="{:id}-trace" class="cake-stack-trace" style="display: none;">' ;
$e .= '{:links}{:info}</div>' ;
2009-07-25 17:27:17 +00:00
$e .= '</pre>' ;
2009-05-01 21:05:46 +00:00
$this -> _templates [ 'js' ][ 'error' ] = $e ;
$t = '<div id="{:id}-trace" class="cake-stack-trace" style="display: none;">' ;
$t .= '{:context}{:code}{:trace}</div>' ;
$this -> _templates [ 'js' ][ 'info' ] = $t ;
$links = array ();
$link = '<a href="javascript:void(0);" onclick="document.getElementById(\'{:id}-code\')' ;
$link .= '.style.display = (document.getElementById(\'{:id}-code\').style.display == ' ;
$link .= '\'none\' ? \'\' : \'none\')">Code</a>' ;
$links [ 'code' ] = $link ;
$link = '<a href="javascript:void(0);" onclick="document.getElementById(\'{:id}-context\')' ;
$link .= '.style.display = (document.getElementById(\'{:id}-context\').style.display == ' ;
$link .= '\'none\' ? \'\' : \'none\')">Context</a>' ;
$links [ 'context' ] = $link ;
$links [ 'help' ] = '<a href="{:helpPath}{:code}" target="_blank">Help</a>' ;
$this -> _templates [ 'js' ][ 'links' ] = $links ;
$this -> _templates [ 'js' ][ 'context' ] = '<pre id="{:id}-context" class="cake-context" ' ;
$this -> _templates [ 'js' ][ 'context' ] .= 'style="display: none;">{:context}</pre>' ;
$this -> _templates [ 'js' ][ 'code' ] = '<div id="{:id}-code" class="cake-code-dump" ' ;
$this -> _templates [ 'js' ][ 'code' ] .= 'style="display: none;"><pre>{:code}</pre></div>' ;
2009-07-25 17:27:17 +00:00
$e = '<pre class="cake-debug"><b>{:error}</b> ({:code}) : {:description} ' ;
2009-05-01 21:05:46 +00:00
$e .= '[<b>{:path}</b>, line <b>{:line}]</b></pre>' ;
$this -> _templates [ 'html' ][ 'error' ] = $e ;
$this -> _templates [ 'html' ][ 'context' ] = '<pre class="cake-debug context"><b>Context</b> ' ;
$this -> _templates [ 'html' ][ 'context' ] .= '<p>{:context}</p></pre>' ;
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Returns a reference to the Debugger singleton object instance .
2008-05-30 11:40:08 +00:00
*
* @ return object
* @ access public
2008-09-25 16:49:56 +00:00
* @ static
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function & getInstance ( $class = null ) {
2008-05-30 11:40:08 +00:00
static $instance = array ();
2008-12-07 20:44:00 +00:00
if ( ! empty ( $class )) {
if ( ! $instance || strtolower ( $class ) != strtolower ( get_class ( $instance [ 0 ]))) {
2010-11-09 01:51:45 +00:00
$instance [ 0 ] = new $class ();
2010-07-06 01:50:36 +00:00
if ( Configure :: read ( 'debug' ) > 0 ) {
2008-12-07 20:44:00 +00:00
$instance [ 0 ] -> helpPath = Configure :: read ( 'Cake.Debugger.HelpPath' );
}
}
}
2008-05-30 11:40:08 +00:00
2008-09-12 05:11:34 +00:00
if ( ! $instance ) {
2010-11-09 01:51:45 +00:00
$instance [ 0 ] = new Debugger ();
2010-07-06 01:50:36 +00:00
if ( Configure :: read ( 'debug' ) > 0 ) {
2008-05-30 11:40:08 +00:00
$instance [ 0 ] -> helpPath = Configure :: read ( 'Cake.Debugger.HelpPath' );
}
}
return $instance [ 0 ];
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Formats and outputs the contents of the supplied variable .
2008-10-12 03:52:24 +00:00
*
2008-09-25 16:49:56 +00:00
* @ param $var mixed the variable to dump
* @ return void
2010-03-28 16:31:52 +00:00
* @ see Debugger :: exportVar ()
2008-09-25 16:49:56 +00:00
* @ static
2010-03-28 15:34:58 +00:00
* @ link http :// book . cakephp . org / view / 1191 / Using - the - Debugger - Class
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function dump ( $var ) {
2010-04-19 04:15:56 +00:00
pr ( self :: exportVar ( $var ));
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2010-03-28 16:31:52 +00:00
* Creates an entry in the log file . The log entry will contain a stack trace from where it was called .
* as well as export the variable using exportVar . By default the log is written to the debug log .
2008-10-12 03:52:24 +00:00
*
2008-09-25 16:49:56 +00:00
* @ param $var mixed Variable or content to log
* @ param $level int type of log to use . Defaults to LOG_DEBUG
* @ return void
* @ static
2010-03-28 15:34:58 +00:00
* @ link http :// book . cakephp . org / view / 1191 / Using - the - Debugger - Class
2008-09-25 16:49:56 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function log ( $var , $level = LOG_DEBUG ) {
2010-04-19 04:15:56 +00:00
$source = self :: trace ( array ( 'start' => 1 )) . " \n " ;
CakeLog :: write ( $level , " \n " . $source . self :: exportVar ( $var ));
2008-05-30 11:40:08 +00:00
}
/**
2008-10-31 20:17:26 +00:00
* Overrides PHP ' s default error handling .
2008-05-30 11:40:08 +00:00
*
* @ param integer $code Code of error
* @ param string $description Error description
* @ param string $file File on which error occurred
* @ param integer $line Line that triggered the error
* @ param array $context Context
* @ return boolean true if error was handled
*/
2010-12-13 02:09:56 +00:00
public static function showError ( $code , $description , $file = null , $line = null , $context = null ) {
2010-11-09 03:06:48 +00:00
$_this = Debugger :: getInstance ();
2008-05-30 11:40:08 +00:00
if ( empty ( $file )) {
$file = '[internal]' ;
}
if ( empty ( $line )) {
$line = '??' ;
}
2010-04-19 04:15:56 +00:00
$path = self :: trimPath ( $file );
2008-05-30 11:40:08 +00:00
$info = compact ( 'code' , 'description' , 'file' , 'line' );
if ( ! in_array ( $info , $_this -> errors )) {
$_this -> errors [] = $info ;
} else {
return ;
}
switch ( $code ) {
case E_PARSE :
case E_ERROR :
case E_CORE_ERROR :
case E_COMPILE_ERROR :
case E_USER_ERROR :
$error = 'Fatal Error' ;
$level = LOG_ERROR ;
break ;
case E_WARNING :
case E_USER_WARNING :
case E_COMPILE_WARNING :
case E_RECOVERABLE_ERROR :
$error = 'Warning' ;
$level = LOG_WARNING ;
break ;
case E_NOTICE :
case E_USER_NOTICE :
$error = 'Notice' ;
$level = LOG_NOTICE ;
break ;
default :
2009-09-10 15:32:21 +00:00
return ;
2008-05-30 11:40:08 +00:00
break ;
}
if ( ! empty ( $_this -> helpPath ) && preg_match ( '/.*\[([0-9]+)\]$/' , $description , $codes )) {
if ( isset ( $codes [ 1 ])) {
2009-05-01 21:05:46 +00:00
$helpID = $codes [ 1 ];
2008-05-30 11:40:08 +00:00
$description = trim ( preg_replace ( '/\[[0-9]+\]$/' , '' , $description ));
}
}
2009-05-01 21:05:46 +00:00
$data = compact (
'level' , 'error' , 'code' , 'helpID' , 'description' , 'file' , 'path' , 'line' , 'context'
);
2010-11-15 03:19:49 +00:00
echo $_this -> outputError ( $data );
2008-05-30 11:40:08 +00:00
if ( $error == 'Fatal Error' ) {
2009-11-19 22:05:59 +00:00
exit ();
2008-05-30 11:40:08 +00:00
}
return true ;
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Outputs a stack trace based on the supplied options .
2008-05-30 11:40:08 +00:00
*
2010-03-28 16:31:52 +00:00
* ### Options
*
* - `depth` - The number of stack frames to return . Defaults to 999
* - `format` - The format you want the return . Defaults to the currently selected format . If
* format is 'array' or 'points' the return will be an array .
* - `args` - Should arguments for functions be shown ? If true , the arguments for each method call
* will be displayed .
* - `start` - The stack frame to start generating a trace from . Defaults to 0
*
2008-05-30 11:40:08 +00:00
* @ param array $options Format for outputting stack trace
2010-03-28 16:31:52 +00:00
* @ return mixed Formatted stack trace
2008-09-25 16:49:56 +00:00
* @ static
2010-03-28 15:34:58 +00:00
* @ link http :// book . cakephp . org / view / 1191 / Using - the - Debugger - Class
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function trace ( $options = array ()) {
2010-11-09 03:06:48 +00:00
$_this = Debugger :: getInstance ();
2009-05-01 21:05:46 +00:00
$defaults = array (
'depth' => 999 ,
'format' => $_this -> _outputFormat ,
'args' => false ,
'start' => 0 ,
'scope' => null ,
'exclude' => null
2008-05-30 11:40:08 +00:00
);
2009-05-01 21:05:46 +00:00
$options += $defaults ;
2008-05-30 11:40:08 +00:00
$backtrace = debug_backtrace ();
2008-09-18 03:09:19 +00:00
$count = count ( $backtrace );
2009-05-01 21:05:46 +00:00
$back = array ();
$_trace = array (
'line' => '??' ,
'file' => '[internal]' ,
'class' => null ,
'function' => '[main]'
);
2008-05-30 11:40:08 +00:00
2008-09-18 03:09:19 +00:00
for ( $i = $options [ 'start' ]; $i < $count && $i < $options [ 'depth' ]; $i ++ ) {
2009-05-01 21:05:46 +00:00
$trace = array_merge ( array ( 'file' => '[internal]' , 'line' => '??' ), $backtrace [ $i ]);
2008-05-30 11:40:08 +00:00
if ( isset ( $backtrace [ $i + 1 ])) {
2009-05-01 21:05:46 +00:00
$next = array_merge ( $_trace , $backtrace [ $i + 1 ]);
$reference = $next [ 'function' ];
2008-05-30 11:40:08 +00:00
if ( ! empty ( $next [ 'class' ])) {
2009-05-01 21:05:46 +00:00
$reference = $next [ 'class' ] . '::' . $reference . '(' ;
2008-05-30 11:40:08 +00:00
if ( $options [ 'args' ] && isset ( $next [ 'args' ])) {
$args = array ();
foreach ( $next [ 'args' ] as $arg ) {
$args [] = Debugger :: exportVar ( $arg );
}
2009-05-01 21:05:46 +00:00
$reference .= join ( ', ' , $args );
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
$reference .= ')' ;
2008-05-30 11:40:08 +00:00
}
} else {
2009-05-01 21:05:46 +00:00
$reference = '[main]' ;
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
if ( in_array ( $reference , array ( 'call_user_func_array' , 'trigger_error' ))) {
2008-05-30 11:40:08 +00:00
continue ;
}
if ( $options [ 'format' ] == 'points' && $trace [ 'file' ] != '[internal]' ) {
$back [] = array ( 'file' => $trace [ 'file' ], 'line' => $trace [ 'line' ]);
2009-05-01 21:05:46 +00:00
} elseif ( $options [ 'format' ] == 'array' ) {
2008-05-30 11:40:08 +00:00
$back [] = $trace ;
2009-05-01 21:05:46 +00:00
} else {
if ( isset ( $_this -> _templates [ $options [ 'format' ]][ 'traceLine' ])) {
$tpl = $_this -> _templates [ $options [ 'format' ]][ 'traceLine' ];
} else {
$tpl = $_this -> _templates [ 'base' ][ 'traceLine' ];
}
2010-04-19 04:15:56 +00:00
$trace [ 'path' ] = self :: trimPath ( $trace [ 'file' ]);
2009-05-01 21:05:46 +00:00
$trace [ 'reference' ] = $reference ;
unset ( $trace [ 'object' ], $trace [ 'args' ]);
$back [] = String :: insert ( $tpl , $trace , array ( 'before' => '{:' , 'after' => '}' ));
2008-05-30 11:40:08 +00:00
}
}
if ( $options [ 'format' ] == 'array' || $options [ 'format' ] == 'points' ) {
return $back ;
}
2009-11-19 22:13:35 +00:00
return implode ( " \n " , $back );
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
* Shortens file paths by replacing the application base path with 'APP' , and the CakePHP core
2008-10-31 20:17:26 +00:00
* path with 'CORE' .
2008-05-30 11:40:08 +00:00
*
* @ param string $path Path to shorten
* @ return string Normalized path
2008-09-25 16:49:56 +00:00
* @ static
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function trimPath ( $path ) {
2008-05-30 11:40:08 +00:00
if ( ! defined ( 'CAKE_CORE_INCLUDE_PATH' ) || ! defined ( 'APP' )) {
return $path ;
}
if ( strpos ( $path , APP ) === 0 ) {
return str_replace ( APP , 'APP' . DS , $path );
} elseif ( strpos ( $path , CAKE_CORE_INCLUDE_PATH ) === 0 ) {
return str_replace ( CAKE_CORE_INCLUDE_PATH , 'CORE' , $path );
} elseif ( strpos ( $path , ROOT ) === 0 ) {
return str_replace ( ROOT , 'ROOT' , $path );
}
2011-04-17 10:35:21 +00:00
if ( strpos ( $path , CAKE ) === 0 ) {
2011-03-12 05:02:44 +00:00
return str_replace ( $corePath , 'CORE' . DS , $path );
2008-05-30 11:40:08 +00:00
}
return $path ;
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
* Grabs an excerpt from a file and highlights a given line of code
*
* @ param string $file Absolute path to a PHP file
* @ param integer $line Line number to highlight
* @ param integer $context Number of lines of context to extract above and below $line
* @ return array Set of lines highlighted
2008-09-25 16:49:56 +00:00
* @ static
2010-03-28 15:34:58 +00:00
* @ link http :// book . cakephp . org / view / 1191 / Using - the - Debugger - Class
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function excerpt ( $file , $line , $context = 2 ) {
2011-04-22 20:00:08 +00:00
$lines = array ();
2008-10-18 01:23:33 +00:00
if ( ! file_exists ( $file )) {
return array ();
}
2008-05-30 11:40:08 +00:00
$data = @ explode ( " \n " , file_get_contents ( $file ));
if ( empty ( $data ) || ! isset ( $data [ $line ])) {
return ;
}
for ( $i = $line - ( $context + 1 ); $i < $line + $context ; $i ++ ) {
if ( ! isset ( $data [ $i ])) {
continue ;
}
$string = str_replace ( array ( " \r \n " , " \n " ), " " , highlight_string ( $data [ $i ], true ));
if ( $i == $line ) {
$lines [] = '<span class="code-highlight">' . $string . '</span>' ;
} else {
$lines [] = $string ;
}
}
return $lines ;
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Converts a variable to a string for debug output .
2008-05-30 11:40:08 +00:00
*
* @ param string $var Variable to convert
* @ return string Variable as a formatted string
2008-09-25 16:49:56 +00:00
* @ static
2010-03-28 15:34:58 +00:00
* @ link http :// book . cakephp . org / view / 1191 / Using - the - Debugger - Class
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function exportVar ( $var , $recursion = 0 ) {
2008-10-23 00:10:44 +00:00
switch ( strtolower ( gettype ( $var ))) {
2008-05-30 11:40:08 +00:00
case 'boolean' :
2008-07-30 20:34:01 +00:00
return ( $var ) ? 'true' : 'false' ;
2008-05-30 11:40:08 +00:00
break ;
case 'integer' :
case 'double' :
return $var ;
break ;
case 'string' :
if ( trim ( $var ) == " " ) {
return '""' ;
}
return '"' . h ( $var ) . '"' ;
break ;
case 'object' :
2010-04-19 04:15:56 +00:00
return get_class ( $var ) . " \n " . self :: _object ( $var );
2008-05-30 11:40:08 +00:00
case 'array' :
2011-06-24 08:12:08 +00:00
$var = array_merge ( $var , array_intersect_key ( array (
'password' => '*****' ,
'login' => '*****' ,
'host' => '*****' ,
'database' => '*****' ,
'port' => '*****' ,
'prefix' => '*****' ,
'schema' => '*****'
), $var ));
2008-05-30 11:40:08 +00:00
$out = " array( " ;
$vars = array ();
foreach ( $var as $key => $val ) {
if ( $recursion >= 0 ) {
if ( is_numeric ( $key )) {
2010-04-19 04:15:56 +00:00
$vars [] = " \n \t " . self :: exportVar ( $val , $recursion - 1 );
2008-05-30 11:40:08 +00:00
} else {
2010-04-19 04:15:56 +00:00
$vars [] = " \n \t " . self :: exportVar ( $key , $recursion - 1 )
. ' => ' . self :: exportVar ( $val , $recursion - 1 );
2008-05-30 11:40:08 +00:00
}
}
}
$n = null ;
2009-11-21 20:14:21 +00:00
if ( ! empty ( $vars )) {
2008-05-30 11:40:08 +00:00
$n = " \n " ;
}
2009-11-19 22:13:35 +00:00
return $out . implode ( " , " , $vars ) . " { $n } ) " ;
2008-05-30 11:40:08 +00:00
break ;
case 'resource' :
return strtolower ( gettype ( $var ));
break ;
case 'null' :
return 'null' ;
break ;
}
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-31 20:17:26 +00:00
* Handles object to string conversion .
2008-05-30 11:40:08 +00:00
*
* @ param string $var Object to convert
2008-09-25 16:49:56 +00:00
* @ return string
2010-03-28 16:31:52 +00:00
* @ see Debugger :: exportVar ()
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:15:56 +00:00
protected static function _object ( $var ) {
2008-05-30 11:40:08 +00:00
$out = array ();
2008-10-23 00:10:44 +00:00
if ( is_object ( $var )) {
2008-05-30 11:40:08 +00:00
$className = get_class ( $var );
$objectVars = get_object_vars ( $var );
2008-10-23 00:10:44 +00:00
foreach ( $objectVars as $key => $value ) {
if ( is_object ( $value )) {
2008-05-30 11:40:08 +00:00
$value = get_class ( $value ) . ' object' ;
} elseif ( is_array ( $value )) {
$value = 'array' ;
} elseif ( $value === null ) {
$value = 'NULL' ;
} elseif ( in_array ( gettype ( $value ), array ( 'boolean' , 'integer' , 'double' , 'string' , 'array' , 'resource' ))) {
$value = Debugger :: exportVar ( $value );
}
$out [] = " $className :: $ $key = " . $value ;
}
}
2009-11-19 22:13:35 +00:00
return implode ( " \n " , $out );
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2009-05-01 21:05:46 +00:00
* Switches output format , updates format strings
2008-05-30 11:40:08 +00:00
*
2009-05-01 21:05:46 +00:00
* @ param string $format Format to use , including 'js' for JavaScript - enhanced HTML , 'html' for
2010-03-28 16:31:52 +00:00
* straight HTML output , or 'txt' for unformatted text .
* @ param array $strings Template strings to be used for the output format .
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public function output ( $format = null , $strings = array ()) {
2010-11-09 03:06:48 +00:00
$_this = Debugger :: getInstance ();
2008-05-30 11:40:08 +00:00
$data = null ;
2009-05-01 21:05:46 +00:00
if ( is_null ( $format )) {
return $_this -> _outputFormat ;
}
if ( ! empty ( $strings )) {
if ( isset ( $_this -> _templates [ $format ])) {
if ( isset ( $strings [ 'links' ])) {
$_this -> _templates [ $format ][ 'links' ] = array_merge (
$_this -> _templates [ $format ][ 'links' ],
$strings [ 'links' ]
);
unset ( $strings [ 'links' ]);
}
$_this -> _templates [ $format ] = array_merge ( $_this -> _templates [ $format ], $strings );
} else {
$_this -> _templates [ $format ] = $strings ;
}
return $_this -> _templates [ $format ];
}
if ( $format === true && ! empty ( $_this -> _data )) {
$data = $_this -> _data ;
$_this -> _data = array ();
2008-05-30 11:40:08 +00:00
$format = false ;
}
2008-12-07 20:44:00 +00:00
$_this -> _outputFormat = $format ;
2008-05-30 11:40:08 +00:00
return $data ;
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2010-11-15 03:06:18 +00:00
* Takes a processed array of data from an error and displays it in the chosen format .
2008-05-30 11:40:08 +00:00
*
2011-04-17 10:35:21 +00:00
* @ param string $data
2010-11-15 03:06:18 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2010-11-15 03:06:18 +00:00
public function outputError ( $data ) {
2009-05-01 21:05:46 +00:00
$defaults = array (
'level' => 0 ,
'error' => 0 ,
'code' => 0 ,
'helpID' => null ,
'description' => '' ,
'file' => '' ,
'line' => 0 ,
2010-11-15 03:06:18 +00:00
'context' => array (),
'start' => 2
2009-05-01 21:05:46 +00:00
);
$data += $defaults ;
2010-11-15 03:06:18 +00:00
$files = $this -> trace ( array ( 'start' => $data [ 'start' ], 'format' => 'points' ));
2009-05-01 21:05:46 +00:00
$code = $this -> excerpt ( $files [ 0 ][ 'file' ], $files [ 0 ][ 'line' ] - 1 , 1 );
2010-11-15 03:06:18 +00:00
$trace = $this -> trace ( array ( 'start' => $data [ 'start' ], 'depth' => '20' ));
2009-05-01 21:05:46 +00:00
$insertOpts = array ( 'before' => '{:' , 'after' => '}' );
2008-05-30 11:40:08 +00:00
$context = array ();
2009-05-01 21:05:46 +00:00
$links = array ();
$info = '' ;
2008-05-30 11:40:08 +00:00
2009-05-01 21:05:46 +00:00
foreach (( array ) $data [ 'context' ] as $var => $value ) {
2008-10-12 03:52:24 +00:00
$context [] = " \$ { $var } \t = \t " . $this -> exportVar ( $value , 1 );
2008-05-30 11:40:08 +00:00
}
2008-12-07 20:44:00 +00:00
switch ( $this -> _outputFormat ) {
2009-05-01 21:05:46 +00:00
case false :
$this -> _data [] = compact ( 'context' , 'trace' ) + $data ;
return ;
case 'log' :
$this -> log ( compact ( 'context' , 'trace' ) + $data );
return ;
}
2008-05-30 11:40:08 +00:00
2009-05-01 21:05:46 +00:00
if ( empty ( $this -> _outputFormat ) || ! isset ( $this -> _templates [ $this -> _outputFormat ])) {
$this -> _outputFormat = 'js' ;
}
2011-05-05 03:30:24 +00:00
$data [ 'id' ] = 'cakeErr' . uniqid ();
2009-05-01 21:05:46 +00:00
$tpl = array_merge ( $this -> _templates [ 'base' ], $this -> _templates [ $this -> _outputFormat ]);
$insert = array ( 'context' => join ( " \n " , $context ), 'helpPath' => $this -> helpPath ) + $data ;
$detect = array ( 'help' => 'helpID' , 'context' => 'context' );
if ( isset ( $tpl [ 'links' ])) {
foreach ( $tpl [ 'links' ] as $key => $val ) {
if ( isset ( $detect [ $key ]) && empty ( $insert [ $detect [ $key ]])) {
continue ;
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
$links [ $key ] = String :: insert ( $val , $insert , $insertOpts );
}
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
foreach ( array ( 'code' , 'context' , 'trace' ) as $key ) {
if ( empty ( $$key ) || ! isset ( $tpl [ $key ])) {
continue ;
}
if ( is_array ( $$key )) {
$$key = join ( " \n " , $$key );
}
$info .= String :: insert ( $tpl [ $key ], compact ( $key ) + $insert , $insertOpts );
}
$links = join ( ' | ' , $links );
unset ( $data [ 'context' ]);
echo String :: insert ( $tpl [ 'error' ], compact ( 'links' , 'info' ) + $data , $insertOpts );
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
/**
2010-01-15 21:56:26 +00:00
* Verifies that the application ' s salt and cipher seed value has been changed from the default value .
2008-05-30 11:40:08 +00:00
*
2008-09-25 16:49:56 +00:00
* @ static
2008-05-30 11:40:08 +00:00
*/
2010-04-19 04:10:22 +00:00
public static function checkSecurityKeys () {
2008-05-30 11:40:08 +00:00
if ( Configure :: read ( 'Security.salt' ) == 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi' ) {
2011-06-20 00:28:40 +00:00
trigger_error ( __d ( 'cake_dev' , 'Please change the value of \'Security.salt\' in app/Config/core.php to a salt value specific to your application' ), E_USER_NOTICE );
2008-05-30 11:40:08 +00:00
}
2010-01-15 21:56:26 +00:00
2010-02-03 10:09:52 +00:00
if ( Configure :: read ( 'Security.cipherSeed' ) === '76859309657453542496749683645' ) {
2011-06-20 00:28:40 +00:00
trigger_error ( __d ( 'cake_dev' , 'Please change the value of \'Security.cipherSeed\' in app/Config/core.php to a numeric (digits only) seed value specific to your application' ), E_USER_NOTICE );
2010-01-15 21:56:26 +00:00
}
2008-05-30 11:40:08 +00:00
}
2009-05-01 21:05:46 +00:00
2008-05-30 11:40:08 +00:00
}