diff --git a/examples/Nette/Debug.php b/examples/Nette/Debug.php index a6e80791..0a82c9a8 100644 --- a/examples/Nette/Debug.php +++ b/examples/Nette/Debug.php @@ -28,7 +28,8 @@ extends InvalidArgumentException{}class InvalidStateException extends -RuntimeException{}class +RuntimeException{function +__construct($message='',$code=0,Exception$previous=NULL){if(version_compare(PHP_VERSION,'5.3','<')){$this->previous=$previous;parent::__construct($message,$code);}else{parent::__construct($message,$code,$previous);}}}class NotImplementedException extends LogicException{}class @@ -52,14 +53,16 @@ extends IOException{}class FatalErrorException extends -Exception{public +Exception{private$severity;public function -__construct($message,$code,$severity,$file,$line,$context){parent::__construct($message,$code);$this->file=$file;$this->line=$line;$this->context=$context;}}final +__construct($message,$code,$severity,$file,$line,$context){parent::__construct($message,$code);$this->severity=$severity;$this->file=$file;$this->line=$line;$this->context=$context;}public +function +getSeverity(){return$this->severity;}}final class Framework{const NAME='Nette Framework';const -VERSION='0.8';const -REVISION='283 released on 2009/04/19 16:54:34';final +VERSION='0.9';const +REVISION='375 released on 2009/06/26 10:12:40';final public function __construct(){throw @@ -73,30 +76,29 @@ static function promo($xhtml=TRUE){echo'Powered by Nette Framework':'>'),'';}}final class -Debug{const +Debug{public +static$productionMode;public +static$consoleMode;public +static$time;private +static$firebugDetected;private +static$ajaxDetected;public +static$maxDepth=3;public +static$maxLen=150;public +static$showLocation=FALSE;const DEVELOPMENT=FALSE;const PRODUCTION=TRUE;const DETECT=NULL;public -static$counters=array();public -static$html;public -static$productionMode;public -static$consoleMode;public -static$maxDepth=3;public -static$maxLen=150;public -static$keysToHide=array('password','passwd','pass','pwd','creditcard','credit card','cc','pin');private +static$strictMode=FALSE;public +static$onFatalError=array();public +static$mailer=array(__CLASS__,'defaultMailer');private static$enabled=FALSE;private -static$enabledProfiler=FALSE;private -static$firebugDetected;private -static$ajaxDetected;private static$logFile;private static$logHandle;private static$sendEmails;private -static$emailHeaders=array('To'=>'','From'=>'noreply@%host%','X-Mailer'=>'Nette Framework','Subject'=>'PHP: An error occurred on the server %host%','Body'=>'[%date%] %message%');public -static$mailer=array(__CLASS__,'defaultMailer');public -static$emailProbability=0.01;private +static$emailHeaders=array('To'=>'','From'=>'noreply@%host%','X-Mailer'=>'Nette Framework','Subject'=>'PHP: An error occurred on the server %host%','Body'=>'[%date%] %message%');private static$colophons=array(array(__CLASS__,'getDefaultColophons'));private -static$keyFilter=array();public -static$time;const +static$enabledProfiler=FALSE;public +static$counters=array();const LOG='LOG';const INFO='INFO';const WARN='WARN';const @@ -115,23 +117,188 @@ function init(){self::$time=microtime(TRUE);self::$consoleMode=PHP_SAPI==='cli';self::$productionMode=self::DETECT;self::$firebugDetected=isset($_SERVER['HTTP_USER_AGENT'])&&strpos($_SERVER['HTTP_USER_AGENT'],'FirePHP/');self::$ajaxDetected=isset($_SERVER['HTTP_X_REQUESTED_WITH'])&&$_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';}public static function -dump($var,$return=FALSE){if(!$return&&self::$productionMode){return$var;}$output="
".self::_dump($var,0)."
\n";if(self::$consoleMode){$output=htmlspecialchars_decode(strip_tags($output),ENT_NOQUOTES);}if($return){return$output;}else{echo$output;return$var;}}private +dump($var,$return=FALSE){if(!$return&&self::$productionMode){return$var;}$output="
".self::_dump($var,0)."
\n";if(self::$showLocation){$trace=debug_backtrace();if(isset($trace[0]['file'],$trace[0]['line'])){$output=substr_replace($output,' '.htmlspecialchars("in file {$trace[0]['file']} on line {$trace[0]['line']}",ENT_NOQUOTES).'',-8,0);}}if(self::$consoleMode){$output=htmlspecialchars_decode(strip_tags($output),ENT_NOQUOTES);}if($return){return$output;}else{echo$output;return$var;}}public static function -_dump(&$var,$level){if(is_bool($var)){return"bool(".($var?'TRUE':'FALSE').")\n";}elseif($var===NULL){return"NULL\n";}elseif(is_int($var)){return"int($var)\n";}elseif(is_float($var)){return"float($var)\n";}elseif(is_string($var)){if(self::$maxLen&&strlen($var)>self::$maxLen){$s=htmlSpecialChars(substr($var,0,self::$maxLen),ENT_NOQUOTES).' ... ';}else{$s=htmlSpecialChars($var,ENT_NOQUOTES);}return"string(".strlen($var).") \"$s\"\n";}elseif(is_array($var)){$s="array(".count($var).") {\n";$space=str_repeat(' ',$level);static$marker;if($marker===NULL)$marker=uniqid("\x00",TRUE);if(isset($var[$marker])){$s.="$space *RECURSION*\n";}elseif($level&$v){if($k===$marker)continue;$s.="$space ".(is_int($k)?$k:"\"$k\"")." => ";if(self::$keyFilter&&is_string($v)&&isset(self::$keyFilter[strtolower($k)])){$s.="string(?) *** hidden ***\n";}else{$s.=self::_dump($v,$level+1);}}unset($var[$marker]);}else{$s.="$space ...\n";}return$s."$space}\n";}elseif(is_object($var)){$arr=(array)$var;$s="object(".get_class($var).") (".count($arr).") {\n";$space=str_repeat(' ',$level);static$list=array();if(in_array($var,$list,TRUE)){$s.="$space *RECURSION*\n";}elseif($level&$v){$m='';if($k[0]==="\x00"){$m=$k[1]==='*'?' protected':' private';$k=substr($k,strrpos($k,"\x00")+1);}$s.="$space \"$k\"$m => ";if(self::$keyFilter&&is_string($v)&&isset(self::$keyFilter[strtolower($k)])){$s.="string(?) *** hidden ***\n";}else{$s.=self::_dump($v,$level+1);}}array_pop($list);}else{$s.="$space ...\n";}return$s."$space}\n";}elseif(is_resource($var)){return"resource of type(".get_resource_type($var).")\n";}else{return"unknown type\n";}}public +consoleDump($var,$title=NULL){if(!self::$productionMode){if(!function_exists('_netteDumpCb2')){function +_netteDumpCb2($m){return"$m[1]$m[2]($m[3]) ".($m[3]<7?' ':' ";}else{$s.="{\n$space$space1...\n$space}";}return$s."\n";}elseif(is_object($var)){$arr=(array)$var;$s="object(".get_class($var).") (".count($arr).") ";$space=str_repeat($space1=' ',$level);static$list=array();if(empty($arr)){$s.="{}";}elseif(in_array($var,$list,TRUE)){$s.="{\n$space$space1*RECURSION*\n$space}";}elseif($level{\n";$list[]=$var;foreach($arr +as$k=>&$v){$m='';if($k[0]==="\x00"){$m=$k[1]==='*'?' protected':' private';$k=substr($k,strrpos($k,"\x00")+1);}$s.="$space$space1\"$k\"$m => ".self::_dump($v,$level+1);}array_pop($list);$s.="$space}";}else{$s.="{\n$space$space1...\n$space}";}return$s."\n";}elseif(is_resource($var)){return"resource of type(".get_resource_type($var).")\n";}else{return"unknown type\n";}}public static function timer($name=NULL){static$time=array();$now=microtime(TRUE);$delta=isset($time[$name])?$now-$time[$name]:0;$time[$name]=$now;return$delta;}public static function -enable($productionMode=NULL,$logFile=NULL,$email=NULL){if(version_compare(PHP_VERSION,'5.2.1')===0){throw -new -NotSupportedException(__METHOD__.' is not supported in PHP 5.2.1');}error_reporting(E_ALL|E_STRICT);if(is_bool($productionMode)){self::$productionMode=$productionMode;}if(self::$productionMode===self::DETECT){if(class_exists('Environment')){self::$productionMode=Environment::isProduction();}elseif(isset($_SERVER['SERVER_ADDR'])||isset($_SERVER['LOCAL_ADDR'])){$addr=isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['LOCAL_ADDR'];$oct=explode('.',$addr);self::$productionMode=$addr!=='::1'&&(count($oct)!==4||($oct[0]!=='10'&&$oct[0]!=='127'&&($oct[0]!=='172'||$oct[1]<16||$oct[1]>31)&&($oct[0]!=='169'||$oct[1]!=='254')&&($oct[0]!=='192'||$oct[1]!=='168')));}else{self::$productionMode=!self::$consoleMode;}}if(self::$productionMode&&$logFile!==FALSE){self::$logFile='log/php_error.log';if(class_exists('Environment')){if(is_string($logFile)){self::$logFile=Environment::expand($logFile);}else +enable($mode=NULL,$logFile=NULL,$email=NULL){error_reporting(E_ALL|E_STRICT);if(is_bool($mode)){self::$productionMode=$mode;}if(self::$productionMode===self::DETECT){if(class_exists('Environment')){self::$productionMode=Environment::isProduction();}elseif(isset($_SERVER['SERVER_ADDR'])||isset($_SERVER['LOCAL_ADDR'])){$addr=isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['LOCAL_ADDR'];$oct=explode('.',$addr);self::$productionMode=$addr!=='::1'&&(count($oct)!==4||($oct[0]!=='10'&&$oct[0]!=='127'&&($oct[0]!=='172'||$oct[1]<16||$oct[1]>31)&&($oct[0]!=='169'||$oct[1]!=='254')&&($oct[0]!=='192'||$oct[1]!=='168')));}else{self::$productionMode=!self::$consoleMode;}}if(self::$productionMode&&$logFile!==FALSE){self::$logFile='log/php_error.log';if(class_exists('Environment')){if(is_string($logFile)){self::$logFile=Environment::expand($logFile);}else try{self::$logFile=Environment::expand('%logDir%/php_error.log');}catch(InvalidStateException$e){}}elseif(is_string($logFile)){self::$logFile=$logFile;}ini_set('error_log',self::$logFile);}if(function_exists('ini_set')){ini_set('display_errors',!self::$productionMode);ini_set('html_errors',!self::$consoleMode);ini_set('log_errors',(bool)self::$logFile);}elseif(ini_get('log_errors')!=(bool)self::$logFile||(ini_get('display_errors')!=!self::$productionMode&&ini_get('display_errors')!==(self::$productionMode?'stderr':'stdout'))){throw new -NotSupportedException('Function ini_set() must be enabled.');}self::$sendEmails=$logFile&&$email;if(self::$sendEmails){if(is_string($email)){self::$emailHeaders['To']=$email;}elseif(is_array($email)){self::$emailHeaders=$email+self::$emailHeaders;}if(mt_rand()/mt_getrandmax()1,E_CORE_ERROR=>1,E_COMPILE_ERROR=>1,E_USER_ERROR=>1,E_PARSE=>1,E_RECOVERABLE_ERROR=>1);if(isset($fatals[$severity])){throw +errorHandler($severity,$message,$file,$line,$context){if($severity===E_RECOVERABLE_ERROR||$severity===E_USER_ERROR){throw new FatalErrorException($message,0,$severity,$file,$line,$context);}elseif(($severity&error_reporting())!==$severity){return -NULL;}static$types=array(E_WARNING=>'Warning',E_USER_WARNING=>'Warning',E_NOTICE=>'Notice',E_USER_NOTICE=>'Notice',E_STRICT=>'Strict standards',E_DEPRECATED=>'Deprecated',E_USER_DEPRECATED=>'Deprecated');$type=isset($types[$severity])?$types[$severity]:'Unknown error';if(self::$logFile){if(self::$sendEmails){self::sendEmail("$type: $message in $file on line $line");}return +NULL;}elseif(self::$strictMode){self::processException(new +FatalErrorException($message,0,$severity,$file,$line,$context),TRUE);exit;}static$types=array(E_WARNING=>'Warning',E_USER_WARNING=>'Warning',E_NOTICE=>'Notice',E_USER_NOTICE=>'Notice',E_STRICT=>'Strict standards',E_DEPRECATED=>'Deprecated',E_USER_DEPRECATED=>'Deprecated');$type=isset($types[$severity])?$types[$severity]:'Unknown error';if(self::$logFile){if(self::$sendEmails){self::sendEmail("$type: $message in $file on line $line");}return FALSE;}elseif(!self::$productionMode&&self::$firebugDetected&&!headers_sent()){$message=strip_tags($message);self::fireLog("$type: $message in $file on line $line",self::ERROR);return NULL;}return FALSE;}public static function +shutdownHandler(){static$types=array(E_ERROR=>1,E_CORE_ERROR=>1,E_COMPILE_ERROR=>1,E_PARSE=>1);$error=error_get_last();if(isset($types[$error['type']])){if(!headers_sent()){header('HTTP/1.1 500 Internal Server Error');}if(ini_get('html_errors')){$error['message']=html_entity_decode(strip_tags($error['message']));}self::processException(new +FatalErrorException($error['message'],0,$error['type'],$error['file'],$error['line'],NULL),TRUE);}}public +static +function processException(Exception$exception,$outputAllowed=FALSE){if(self::$logFile){error_log("PHP Fatal error: Uncaught $exception");$file=@strftime('%d-%b-%Y %H-%M-%S ',Debug::$time).strstr(number_format(Debug::$time,4,'~',''),'~');$file=dirname(self::$logFile)."/exception $file.html";self::$logHandle=@fopen($file,'x');if(self::$logHandle){ob_start(array(__CLASS__,'writeFile'),1);self::paintBlueScreen($exception);ob_end_flush();fclose(self::$logHandle);}if(self::$sendEmails){self::sendEmail((string)$exception);}}elseif(self::$productionMode){}elseif(self::$consoleMode){if($outputAllowed){echo"$exception\n";foreach(self::$colophons as$callback){foreach((array)call_user_func($callback,'bluescreen')as$line)echo -strip_tags($line)."\n";}}}elseif(self::$firebugDetected&&self::$ajaxDetected&&!headers_sent()){self::fireLog($exception,self::EXCEPTION);}elseif($outputAllowed){self::paintBlueScreen($exception);}elseif(self::$firebugDetected&&!headers_sent()){self::fireLog($exception,self::EXCEPTION);}}public +strip_tags($line)."\n";}}}elseif(self::$firebugDetected&&self::$ajaxDetected&&!headers_sent()){self::fireLog($exception,self::EXCEPTION);}elseif($outputAllowed){self::paintBlueScreen($exception);}elseif(self::$firebugDetected&&!headers_sent()){self::fireLog($exception,self::EXCEPTION);}foreach(self::$onFatalError +as$handler){fixCallback($handler);call_user_func($handler,$exception);}}public static function paintBlueScreen(Exception$exception){$internals=array();foreach(array('Object','ObjectMixin')as$class){if(class_exists($class,FALSE)){$rc=new ReflectionClass($class);$internals[$rc->getFileName()]=TRUE;}}$colophons=self::$colophons;if(!function_exists('_netteDebugPrintCode')){function -_netteDebugPrintCode($file,$line,$count=15){if(function_exists('ini_set')){ini_set('highlight.comment','#999; font-style: italic');ini_set('highlight.default','#000');ini_set('highlight.html','#06b');ini_set('highlight.keyword','#d24; font-weight: bold');ini_set('highlight.string','#080');}$start=max(1,$line-floor($count/2));$source=explode("\n",@highlight_file($file,TRUE));echo$source[0];$source=explode('
',$source[1]);array_unshift($source,NULL);$i=$start;while(--$i>=1){if(preg_match('#.*(]*>)#',$source[$i],$m)){if($m[1]!=='')echo$m[1];break;}}$source=array_slice($source,$start,$count,TRUE);end($source);$numWidth=strlen((string)key($source));foreach($source -as$n=>$s){$s=str_replace(array("\r","\n"),array('',''),$s);if($n===$line){printf("Line %{$numWidth}s: %s\n%s",$n,strip_tags($s),preg_replace('#[^>]*(<[^>]+>)[^<]*#','$1',$s));}else{printf("Line %{$numWidth}s: %s\n",$n,$s);}}echo'';}function +_netteDebugPrintCode($file,$line,$count=15){if(function_exists('ini_set')){ini_set('highlight.comment','#999; font-style: italic');ini_set('highlight.default','#000');ini_set('highlight.html','#06b');ini_set('highlight.keyword','#d24; font-weight: bold');ini_set('highlight.string','#080');}$start=max(1,$line-floor($count/2));$source=explode("\n",@highlight_file($file,TRUE));$spans=1;echo$source[0];$source=explode('
',$source[1]);array_unshift($source,NULL);$i=$start;while(--$i>=1){if(preg_match('#.*(]*>)#',$source[$i],$m)){if($m[1]!==''){$spans++;echo$m[1];}break;}}$source=array_slice($source,$start,$count,TRUE);end($source);$numWidth=strlen((string)key($source));foreach($source +as$n=>$s){$spans+=substr_count($s,'Line %{$numWidth}s: %s\n%s",$n,strip_tags($s),preg_replace('#[^>]*(<[^>]+>)[^<]*#','$1',$s));}else{printf("Line %{$numWidth}s: %s\n",$n,$s);}}echo +str_repeat('',$spans),'';}function +_netteDump($var){return +preg_replace_callback('#(
|\s+)?(.*)\((\d+)\) #','_netteDumpCb',Debug::dump($var,TRUE));}function
+_netteDumpCb($m){return"$m[1]$m[2]($m[3]) ".(trim($m[1])||$m[3]<7?' ':'