From 1662b22231d89353dcecca52ef883087af5807f7 Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Sun, 23 Mar 2014 18:43:03 +0400 Subject: [PATCH] added .php_cs and .editorconfig --- .editorconfig | 5 + .php_cs | 16 + dBug.php | 1822 ++++++++++++++++++++++++------------------------- 3 files changed, 931 insertions(+), 912 deletions(-) create mode 100644 .editorconfig create mode 100644 .php_cs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..37598d6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true +[*] +end_of_line = lf +insert_final_newline = false +indent_style = tab [*.php] charset=utf-8 \ No newline at end of file diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..c97a196 --- /dev/null +++ b/.php_cs @@ -0,0 +1,16 @@ +notName('LICENSE.txt') + ->notName('README.md') + ->notName('dBug.doxyfile') + ->notName('composer.*') + ->exclude('vendor') + ->in(__DIR__) +; + +return Symfony\CS\Config\Config::create() + ->fixers(array('-indentation','-braces','-psr0','-controls_spaces')) + ->finder($finder) +; + diff --git a/dBug.php b/dBug.php index 8bc51b0..949275d 100755 --- a/dBug.php +++ b/dBug.php @@ -1,912 +1,910 @@ -bCollapsed = $bCollapsed; - if(in_array($forceType,$arrAccept)) - $this->{"varIs".ucfirst($forceType)}($var); - else - $this->checkType($var); - } - - //get variable name - function getVariableName() { - $arrBacktrace = debug_backtrace(); - - //possible 'included' functions - $arrInclude = array("include","include_once","require","require_once"); - - //check for any included/required files. if found, get array of the last included file (they contain the right line numbers) - for($i=count($arrBacktrace)-1; $i>=0; $i--) { - $arrCurrent = $arrBacktrace[$i]; - if(array_key_exists("function", $arrCurrent) && - (in_array($arrCurrent["function"], $arrInclude) || (0 != strcasecmp($arrCurrent["function"], "dbug")))) - continue; - - $arrFile = $arrCurrent; - - break; - } - - if(isset($arrFile)) { - $arrLines = file($arrFile["file"]); - $code = $arrLines[($arrFile["line"]-1)]; - - //find call to dBug class - preg_match('/\bnew dBug\s*\(\s*(.+)\s*\);/i', $code, $arrMatches); - - return isset($arrMatches[1])?$arrMatches[1]:'[multiline]'; - } - return ""; - } - - function initializeHeader(&$header){ - if(!$this->bInitialized) { - $header = $this->getVariableName() . " (" . $header . ")"; - $this->bInitialized = true; - } - } - - /*! - @name rendering functions - used to make tables representing different variables - */ - //!@{ - - //!creates the main table header - /*! - @param string $type name of the style of the header cell - @param string $header the text of the header cell - @param integer $colspan colspan property for the header cell - */ - function makeTableHeader($type,$header,$colspan=2) { - $this->initializeHeader($header); - $this->renderTableHeader($type,$header,$colspan); - } - - //!draws the main table header - /*! - @param string $type name of the style of the header cell - @param string $text the text of the header cell - @param integer $colspan colspan property for the header cell - */ - function renderTableHeader($type,$text,$colspan=0){ - echo ' - - - '; - } - - //!renders table of 2 cells in 1 row [type][value] - /*! - @param string $headerStyle name of the style of the header cell - @param string $header the text of the header cell - @param string $value the text of the value cell - @param string $valueStyle name of the style of the value cell - @param integer $colspan colspan property for the header cell - */ - function renderPrimitiveType($headerStyle,$header,$value,$valueStyle=null,$colspan=0){ - if(!$valueStyle)$valueStyle=$headerStyle; - $this->initializeHeader($header); - echo '
bCollapsed) ? 'style="font-style:italic" ' : '').'class="dBug_'.$type.'Header" '.($colspan?'colspan='.$colspan:'').' onClick="dBug_toggleTable(this)">'.$text.'
- - - '; - } - - //!creates the table row header - /*! - @param string $type name of the style of the key cell - @param string $header the text of the key cell - */ - function makeTDHeader($type,$header) { - echo 'bCollapsed ? ' style="display:none"' : '').'> - - \n"; - } - //!@} - - - //!prints error - function error($type) { - $error='Error: Variable cannot be a'; - // this just checks if the type starts with a vowel or "x" and displays either "a" or "an" - if(in_array(substr($type,0,1),array("a","e","i","o","u","x"))) - $error.="n"; - return ($error." ".$type." type"); - } - - //!check variable type andd process the value in right way - function checkType($var) { - $type=gettype($var); - switch($type) { - case 'resource': - $this->varIsResource($var); - break; - case 'object': - $this->varIsObject($var); - break; - case 'array': - $this->varIsArray($var); - break; - case 'integer': - case 'double': - $this->varIsNumeric($var,$type); - break; - case 'NULL': - $this->varIsNULL(); - break; - case 'boolean': - $this->varIsBoolean($var); - break; - case 'string': - $this->varIsString($var); - break; - default: - $var=($var=='') ? '[empty string]' : $var; - echo "
bCollapsed) ? 'style="font-style:italic" ' : '').'class="dBug_'.$headerStyle.'Header" '.($colspan?'colspan='.$colspan:'').' onClick="dBug_toggleRow(this)">' - .$header. - ''.$value.'
'.$header.''; - } - - //!closes table row - function closeTDRow() { - return "
\n\n\n
".$var."
\n"; - break; - } - } - - /*! - @name functions for rendering different types - */ - //!@{ - - //!renders NULL as red-pink rectangle - function varIsNULL() { - $this->makeTableHeader('false','NULL'); - echo ''; - } - - //!renders numeric types : integers and doubles - function varIsNumeric($var,$type) { - $this->renderPrimitiveType('numeric',$type,$var); - echo ''; - } - - /*! - renders string either as primitive type (if it is short (less than $embeddedStringMaxLength chars) - and contains of one line) or line-by-line (otherwise) - */ - function varIsString(&$var){ - if($var==''){ - $this->makeTableHeader('string','empty string'); - echo ''; - return; - } - $length=strlen($var); - $nv=htmlspecialchars($var,ENT_QUOTES | ENT_SUBSTITUTE,''); - $lines=preg_split('/\R/', $nv); - $linesCount=count($lines); - if($linesCount==1 && $length<=self::$embeddedStringMaxLength){ - $this->renderPrimitiveType('string','string ['.$length.']',$var); - }else{ - $this->makeTableHeader('string','string ('.$length.' chars @ '.$linesCount.' lines)'); - foreach($lines as $num=>$line){ - $this->makeTDHeader('string',$num); - echo ($line==''?'[empty line]':$line); - $this->closeTDRow('string'); - } - } - echo ""; - } - - //!renders boolean variable - function varIsBoolean(&$var) { - $var?$this->renderPrimitiveType('boolean','boolean','TRUE','booleanTrue'):$this->renderPrimitiveType('boolean','boolean','FALSE','booleanFalse'); - echo ''; - } - - - function varIsArray(&$var) { - $var_ser = serialize($var); - array_push($this->arrHistory, $var_ser); - - $this->makeTableHeader('array','array'); - if(is_array($var)) { - foreach($var as $key=>$value) { - $this->makeTDHeader('array',$key); - - //check for recursion - if(is_array($value)) { - $var_ser = serialize($value); - if(in_array($var_ser, $this->arrHistory, TRUE)){ - echo '*RECURSION*'; - echo $this->closeTDRow(); - continue; - } - } - - //if(in_array(gettype($value),$this->arrType)) - $this->checkType($value); - /*else { - $value=(trim($value)=="") ? "[empty string]" : $value; - echo $value; - }*/ - echo $this->closeTDRow(); - } - } - else echo ''.$this->error('array').$this->closeTDRow(); - array_pop($this->arrHistory); - echo ''; - } - - - - //! checks wheither variable is object of special type (using varIs*Object), and renders it if it is generic object - function varIsObject(&$var) { - if($this->varIsSpecialObject($var))return 1; - $var_ser = serialize($var); - array_push($this->arrHistory, $var_ser); - - if(is_object($var)) { - $this->makeTableHeader('object','object ( '.get_class($var).' )'); - if(method_exists($var,'__toString')){ - $str=$var->__toString(); - if($str!==null){ - $this->makeTDHeader('string','[string representation]'); - $this->varIsString($str); - echo $this->closeTDRow(); - } - } - $arrObjVars=get_object_vars($var); - foreach($arrObjVars as $key=>$value) { - - //$value=(!is_object($value) && !is_array($value) && trim($value)=="") ? "[empty string]" : $value; - $this->makeTDHeader('object',$key); - - //check for recursion - if(is_object($value)||is_array($value)) { - $var_ser = serialize($value); - if(in_array($var_ser, $this->arrHistory, TRUE)) { - echo (is_object($value)) ? '*RECURSION* -> $'.get_class($value) : '*RECURSION*'; - echo $this->closeTDRow(); - continue; - } - } - //if(in_array(gettype($value),$this->arrType)) - $this->checkType($value); - //else - //echo $value; - echo $this->closeTDRow(); - } - $arrObjMethods=get_class_methods(get_class($var)); - foreach($arrObjMethods as $key=>$value) { - $this->makeTDHeader('object',$value); - echo '[function]'.$this->closeTDRow(); - } - if($var instanceof \Iterator){ - foreach($var as $key=>$value) { - $this->makeTDHeader('array',$key); - $this->checkType($value); - echo $this->closeTDRow(); - } - } - } - else{ - $this->makeTableHeader('object','object'); - echo ''.$this->error('object').$this->closeTDRow(); - } - array_pop($this->arrHistory); - echo ''; - } - - function varIsSpecialObject(&$var){ - if($this->varIsDBObject($var))return 1; - if($var instanceof Exception){ - $this->varIsException($var); - return 1; - } - return 0; - } - - - //!shows info about different resources, uses customized rendering founctions when needed - function varIsResource($var) { - $this->makeTableHeader('resourceC','resource',1); - echo "\n\n"; - $restype=get_resource_type($var); - switch($restype) { - case 'fbsql result': - case 'mssql result': - case 'msql query': - case 'pgsql result': - case 'sybase-db result': - case 'sybase-ct result': - case 'mysql result': - $db=current(explode(' ',$restype)); - $this->varIsDBResource($var,$db); - break; - case 'gd': - $this->varIsGDResource($var); - break; - case 'xml': - $this->varIsXmlResource($var); - break; - case 'curl': - $this->varIsCurlEasyResource($var); - break; - /*case "curl_multi": - $this->varIsCurlMultiResource($var); - break;*/ - default: - echo $restype.$this->closeTDRow(); - break; - } - echo $this->closeTDRow()."\n"; - } - - //!@} - - /*! - @name functions for rendering different resources - */ - //!@{ - - //!shows information about curl easy handles - /*!simply iterates through handle info and displays everything which is not converted into false*/ - function varIsCurlEasyResource(&$var) { - $this->makeTableHeader('resource','curl easy handle',2); - $info=curl_getinfo($var); - foreach($info as $name=>&$piece){ - if($piece){ - $this->makeTDHeader('resource',$name); - //echo $piece.$this->closeTDRow(); - $this->checkType($piece); - echo $this->closeTDRow(); - } - } - unset($info); - echo ''; - - } - //!not implemented yet - function varIsCurlMultiResource(&$var) { - - } - - //!if variable is an image/gd resource type - function varIsGDResource(&$var) { - $this->makeTableHeader('resource','gd',2); - $this->makeTDHeader('resource','Width'); - $this->checkType(imagesx($var)); - echo $this->closeTDRow(); - $this->makeTDHeader('resource','Height'); - $this->checkType(imagesy($var)); - echo $this->closeTDRow(); - $this->makeTDHeader('resource','Colors'); - $this->checkType(imageistruecolor($var)?'TrueColor (16 777 216)':imagecolorstotal($var)); - echo $this->closeTDRow(); - - $this->makeTDHeader('resource','Image'); - - - - ob_start(); - imagepng($var); - $img = ob_get_clean(); - - echo ''.$this->closeTDRow(); - echo ''; - } - - //!@} - - - /*! - @name database results rendering functions - */ - //!@{ - - //!renders either PDO or SQLite3 statement objects - /*!@returns 1 if the object is DB object, 0 otherwise*/ - function varIsDBObject($var) { - $structure=array(); - $data=array(); - $retres=false; - if($var instanceof SQLite3Result){ - //$var=clone $var; - $dbtype=''; - $count=$var->numColumns(); - for($i=0;$i<$count;$i++){ - $structure[$i]=array(); - $structure[$i][0]=$var->columnName($i); - $structure[$i][1]=$var->columnType($i); - } - $var->reset(); - while($res=$var->fetchArray(SQLITE3_NUM)){ - $data[]=$res; - } - $var->reset(); - $dbtype='SQLite3'; - unset($var); - $this->renderDBData($dbtype,$structure,$data); - $retres=true; - } - if($var instanceof PDOStatement){ - //$var=clone $var; - $count=$var->columnCount(); - $col=null; - for($i=0;$i<$count;$i++){ - //$col=$var->getColumnMeta(0); - $col=$var->getColumnMeta($i); - $structure[$i]=array(); - $structure[$i][0]=$col['name']; - $structure[$i][1]=(isset($col['driver:decl_type'])?(isset($col["len"])?"({$col["len"]})":'')."\n":'')."({$col["native_type"]})"; - } - unset($col); - $data=$var->fetchAll(); - $var->closeCursor(); - $dbtype='PDOStatement'; - unset($var); - $this->renderDBData($dbtype,$structure,$data); - $retres=true; - } - unset($dbtype); - unset($data); - unset($structure); - return $retres; - } - - //!renders database data - /*! - @param string $objectType type of the db, it is only the name of header now - @param array $structure 'header' of the table - columns names and types - @param array $data rows of sql request result - */ - function renderDBData(&$objectType,&$structure,&$data){ - $this->makeTableHeader('database',$objectType,count($structure)+1); - echo ' '; - foreach($structure as $field) { - echo ''.$field[0].""; - } - echo ''; - if(empty($data)){ - echo '[empty result]'; - }else - $i=0; - foreach($data as $row) { - echo "\n"; - echo ''.(++$i).''; - for($k=0;$k'.$fieldrow."\n"; - } - echo "\n"; - } - echo ''; - } - - //!renders database resource (fetch result) into table or ... smth else - function varIsDBResource($var,$db='mysql') { - if($db == 'pgsql') - $db = 'pg'; - if($db == 'sybase-db' || $db == 'sybase-ct') - $db = 'sybase'; - $arrFields = array('name','type','flags'); - $numrows=call_user_func($db.'_num_rows',$var); - $numfields=call_user_func($db.'_num_fields',$var); - $this->makeTableHeader('database',$db.' result',$numfields+1); - echo ' '; - for($i=0;$i<$numfields;$i++) { - $field_header = ''; - for($j=0; $j'.$field_name.''; - } - echo ''; - for($i=0;$i<$numrows;$i++) { - $row=call_user_func($db.'_fetch_array',$var,constant(strtoupper($db).'_ASSOC')); - echo "\n"; - echo ''.($i+1).''; - for($k=0;$k<$numfields;$k++) { - $tempField=$field[$k]->name; - $fieldrow=$row[($field[$k]->name)]; - $fieldrow=($fieldrow=='') ? '[empty string]' : $fieldrow; - echo ''.$fieldrow."\n"; - } - echo "\n"; - } - echo ''; - if($numrows>0) - call_user_func($db.'_data_seek',$var,0); - } - //!@} - - - /*! - @name other special kinds of objects rendering functionality - */ - //!@{ - - //!array of properties of every exception to be rendered first - static $exceptionMainProps=array('message','code','file','line'); - //!array of properties of Exception of not to be rendered - static $exceptionExcludedProps=array( - //'xdebug_message', - 'trace' - ); - - //!function used to render exceptions - /*! - Renders exceptions : at first basic fields, then custom fields. - Custom private and protected fields are rendered if reflection api is available - */ - function varIsException(&$var) { - $code=$var->getCode(); - $this->makeTableHeader('Exception',get_class($var).' :: '.$code); - foreach(static::$exceptionMainProps as &$pname) { - $this->makeTDHeader('Exception',$pname); - $this->checkType($var->{'get'.ucfirst($pname)}()); - echo $this->closeTDRow(); - } - unset($pname); - echo ''; - if(extension_loaded('Reflection')){ - $refl=new ReflectionObject($var); - $props=$refl->getProperties(ReflectionProperty::IS_PROTECTED|ReflectionProperty::IS_PRIVATE); - foreach($props as &$prop) { - $pname=$prop->getName(); - if(in_array($pname,static::$exceptionMainProps)||in_array($pname,static::$exceptionExcludedProps))continue; - $this->makeTDHeader('Exception',$pname); - $prop->setAccessible(true); - $this->checkType($prop->getValue($var)); - $prop->setAccessible(false); - echo $this->closeTDRow(); - } - } - - foreach($var as $key=>&$value) { - if($key=='xdebug_message')continue; - $this->makeTDHeader('Exception',$key); - $this->checkType($value); - echo $this->closeTDRow(); - } - - echo ''; - } - - //!@} - - - - /*! - @name xml rendering functions - */ - //!@{ - - //!if variable is an xml type - //!remember, that you must force type to xml to use this - function varIsXml($var) { - $this->varIsXmlResource($var); - } - - //!if variable is an xml resource type - function varIsXmlResource($var) { - $xml_parser=xml_parser_create(); - xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0); - xml_set_element_handler($xml_parser,array(&$this,'xmlStartElement'),array(&$this,'xmlEndElement')); - xml_set_character_data_handler($xml_parser,array(&$this,'xmlCharacterData')); - xml_set_default_handler($xml_parser,array(&$this,'xmlDefaultHandler')); - - $this->makeTableHeader('xml','xml document',2); - $this->makeTDHeader('xml','xmlRoot'); - - //attempt to open xml file - $bFile=(!($fp=@fopen($var,'r'))) ? false : true; - - //read xml file - if($bFile) { - while($data=str_replace("\n",'',fread($fp,4096))) - $this->xmlParse($xml_parser,$data,feof($fp)); - } - //if xml is not a file, attempt to read it as a string - else { - if(!is_string($var)) { - echo $this->error('xml').$this->closeTDRow()."\n"; - return; - } - $data=$var; - $this->xmlParse($xml_parser,$data,1); - } - - echo $this->closeTDRow()."\n"; - - } - - //!parses xml - function xmlParse($xml_parser,$data,$bFinal) { - if (!xml_parse($xml_parser,$data,$bFinal)) { - die(sprintf("XML error: %s at line %d\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser))); - } - } - - //!xml: inititiated when a start tag is encountered - function xmlStartElement($parser,$name,$attribs) { - $this->xmlAttrib[$this->xmlCount]=$attribs; - $this->xmlName[$this->xmlCount]=$name; - $this->xmlSData[$this->xmlCount]='$this->makeTableHeader("xml","xml element",2);'; - $this->xmlSData[$this->xmlCount].='$this->makeTDHeader("xml","xmlName");'; - $this->xmlSData[$this->xmlCount].='echo "'.$this->xmlName[$this->xmlCount].'".$this->closeTDRow();'; - $this->xmlSData[$this->xmlCount].='$this->makeTDHeader("xml","xmlAttributes");'; - if(count($attribs)>0) - $this->xmlSData[$this->xmlCount].='$this->varIsArray($this->xmlAttrib['.$this->xmlCount.']);'; - else - $this->xmlSData[$this->xmlCount].='echo " ";'; - $this->xmlSData[$this->xmlCount].='echo $this->closeTDRow();'; - $this->xmlCount++; - } - - //!xml: initiated when an end tag is encountered - function xmlEndElement($parser,$name) { - for($i=0;$i<$this->xmlCount;$i++) { - eval($this->xmlSData[$i]); - $this->makeTDHeader("xml","xmlText"); - echo (!empty($this->xmlCData[$i])) ? $this->xmlCData[$i] : " "; - echo $this->closeTDRow(); - $this->makeTDHeader("xml","xmlComment"); - echo (!empty($this->xmlDData[$i])) ? $this->xmlDData[$i] : " "; - echo $this->closeTDRow(); - $this->makeTDHeader('xml',"xmlChildren"); - unset($this->xmlCData[$i],$this->xmlDData[$i]); - } - echo $this->closeTDRow(); - echo ''; - $this->xmlCount=0; - } - - //!xml: initiated when text between tags is encountered - function xmlCharacterData($parser,$data) { - $count=$this->xmlCount-1; - if(!empty($this->xmlCData[$count])) - $this->xmlCData[$count].=$data; - else - $this->xmlCData[$count]=$data; - } - - //!@} - - //!xml: initiated when a comment or other miscellaneous texts is encountered - function xmlDefaultHandler($parser,$data) { - //strip '' off comments - $data=str_replace(array("<!--","-->"),"",htmlspecialchars($data)); - $count=$this->xmlCount-1; - if(!empty($this->xmlDData[$count])) - $this->xmlDData[$count].=$data; - else - $this->xmlDData[$count]=$data; - } - - //! adds needed JS and CSS sources to page - static function initJSandCSS() { - echo << - /* code modified from ColdFusion's cfdump code */ - function dBug_toggleRow(source) { - var target = (document.all) ? source.parentElement.cells[1] : source.parentNode.lastChild; - dBug_toggleTarget(target,dBug_toggleSource(source)); - } - - function dBug_toggleSource(source) { - if (source.style.fontStyle=='italic') { - source.style.fontStyle='normal'; - source.title='click to collapse'; - return 'open'; - } else { - source.style.fontStyle='italic'; - source.title='click to expand'; - return 'closed'; - } - } - - function dBug_toggleTarget(target,switchToState) { - target.style.display = (switchToState=='open') ? '' : 'none'; - } - - function dBug_toggleTable(source) { - var switchToState=dBug_toggleSource(source); - if(document.all) { - var table=source.parentElement.parentElement; - for(var i=1;i - - -SCRIPTS; - } - -} -?> \ No newline at end of file +bCollapsed = $bCollapsed; + if(in_array($forceType,$arrAccept)) + $this->{"varIs".ucfirst($forceType)}($var); + else + $this->checkType($var); + } + + //get variable name + function getVariableName() { + $arrBacktrace = debug_backtrace(); + + //possible 'included' functions + $arrInclude = array("include","include_once","require","require_once"); + + //check for any included/required files. if found, get array of the last included file (they contain the right line numbers) + for($i=count($arrBacktrace)-1; $i>=0; $i--) { + $arrCurrent = $arrBacktrace[$i]; + if(array_key_exists("function", $arrCurrent) && + (in_array($arrCurrent["function"], $arrInclude) || (0 != strcasecmp($arrCurrent["function"], "dbug")))) + continue; + + $arrFile = $arrCurrent; + + break; + } + + if(isset($arrFile)) { + $arrLines = file($arrFile["file"]); + $code = $arrLines[($arrFile["line"]-1)]; + + //find call to dBug class + preg_match('/\bnew dBug\s*\(\s*(.+)\s*\);/i', $code, $arrMatches); + + return isset($arrMatches[1])?$arrMatches[1]:'[multiline]'; + } + return ""; + } + + function initializeHeader(&$header){ + if(!$this->bInitialized) { + $header = $this->getVariableName() . " (" . $header . ")"; + $this->bInitialized = true; + } + } + + /*! + @name rendering functions + used to make tables representing different variables + */ + //!@{ + + //!creates the main table header + /*! + @param string $type name of the style of the header cell + @param string $header the text of the header cell + @param integer $colspan colspan property for the header cell + */ + function makeTableHeader($type,$header,$colspan=2) { + $this->initializeHeader($header); + $this->renderTableHeader($type,$header,$colspan); + } + + //!draws the main table header + /*! + @param string $type name of the style of the header cell + @param string $text the text of the header cell + @param integer $colspan colspan property for the header cell + */ + function renderTableHeader($type,$text,$colspan=0){ + echo ' + + + '; + } + + //!renders table of 2 cells in 1 row [type][value] + /*! + @param string $headerStyle name of the style of the header cell + @param string $header the text of the header cell + @param string $value the text of the value cell + @param string $valueStyle name of the style of the value cell + @param integer $colspan colspan property for the header cell + */ + function renderPrimitiveType($headerStyle,$header,$value,$valueStyle=null,$colspan=0){ + if(!$valueStyle)$valueStyle=$headerStyle; + $this->initializeHeader($header); + echo '
bCollapsed) ? 'style="font-style:italic" ' : '').'class="dBug_'.$type.'Header" '.($colspan?'colspan='.$colspan:'').' onClick="dBug_toggleTable(this)">'.$text.'
+ + + '; + } + + //!creates the table row header + /*! + @param string $type name of the style of the key cell + @param string $header the text of the key cell + */ + function makeTDHeader($type,$header) { + echo 'bCollapsed ? ' style="display:none"' : '').'> + + \n"; + } + //!@} + + + //!prints error + function error($type) { + $error='Error: Variable cannot be a'; + // this just checks if the type starts with a vowel or "x" and displays either "a" or "an" + if(in_array(substr($type,0,1),array("a","e","i","o","u","x"))) + $error.="n"; + return ($error." ".$type." type"); + } + + //!check variable type andd process the value in right way + function checkType($var) { + $type=gettype($var); + switch($type) { + case 'resource': + $this->varIsResource($var); + break; + case 'object': + $this->varIsObject($var); + break; + case 'array': + $this->varIsArray($var); + break; + case 'integer': + case 'double': + $this->varIsNumeric($var,$type); + break; + case 'NULL': + $this->varIsNULL(); + break; + case 'boolean': + $this->varIsBoolean($var); + break; + case 'string': + $this->varIsString($var); + break; + default: + $var=($var=='') ? '[empty string]' : $var; + echo "
bCollapsed) ? 'style="font-style:italic" ' : '').'class="dBug_'.$headerStyle.'Header" '.($colspan?'colspan='.$colspan:'').' onClick="dBug_toggleRow(this)">' + .$header. + ''.$value.'
'.$header.''; + } + + //!closes table row + function closeTDRow() { + return "
\n\n\n
".$var."
\n"; + break; + } + } + + /*! + @name functions for rendering different types + */ + //!@{ + + //!renders NULL as red-pink rectangle + function varIsNULL() { + $this->makeTableHeader('false','NULL'); + echo ''; + } + + //!renders numeric types : integers and doubles + function varIsNumeric($var,$type) { + $this->renderPrimitiveType('numeric',$type,$var); + echo ''; + } + + /*! + renders string either as primitive type (if it is short (less than $embeddedStringMaxLength chars) + and contains of one line) or line-by-line (otherwise) + */ + function varIsString(&$var){ + if($var==''){ + $this->makeTableHeader('string','empty string'); + echo ''; + return; + } + $length=strlen($var); + $nv=htmlspecialchars($var,ENT_QUOTES | ENT_SUBSTITUTE,''); + $lines=preg_split('/\R/', $nv); + $linesCount=count($lines); + if($linesCount==1 && $length<=self::$embeddedStringMaxLength){ + $this->renderPrimitiveType('string','string ['.$length.']',$var); + }else{ + $this->makeTableHeader('string','string ('.$length.' chars @ '.$linesCount.' lines)'); + foreach($lines as $num=>$line){ + $this->makeTDHeader('string',$num); + echo ($line==''?'[empty line]':$line); + $this->closeTDRow('string'); + } + } + echo ""; + } + + //!renders boolean variable + function varIsBoolean(&$var) { + $var?$this->renderPrimitiveType('boolean','boolean','TRUE','booleanTrue'):$this->renderPrimitiveType('boolean','boolean','FALSE','booleanFalse'); + echo ''; + } + + + function varIsArray(&$var) { + $var_ser = serialize($var); + array_push($this->arrHistory, $var_ser); + + $this->makeTableHeader('array','array'); + if(is_array($var)) { + foreach($var as $key=>$value) { + $this->makeTDHeader('array',$key); + + //check for recursion + if(is_array($value)) { + $var_ser = serialize($value); + if(in_array($var_ser, $this->arrHistory, TRUE)){ + echo '*RECURSION*'; + echo $this->closeTDRow(); + continue; + } + } + + //if(in_array(gettype($value),$this->arrType)) + $this->checkType($value); + /*else { + $value=(trim($value)=="") ? "[empty string]" : $value; + echo $value; + }*/ + echo $this->closeTDRow(); + } + } + else echo ''.$this->error('array').$this->closeTDRow(); + array_pop($this->arrHistory); + echo ''; + } + + + + //! checks wheither variable is object of special type (using varIs*Object), and renders it if it is generic object + function varIsObject(&$var) { + if($this->varIsSpecialObject($var))return 1; + $var_ser = serialize($var); + array_push($this->arrHistory, $var_ser); + + if(is_object($var)) { + $this->makeTableHeader('object','object ( '.get_class($var).' )'); + if(method_exists($var,'__toString')){ + $str=$var->__toString(); + if($str!==null){ + $this->makeTDHeader('string','[string representation]'); + $this->varIsString($str); + echo $this->closeTDRow(); + } + } + $arrObjVars=get_object_vars($var); + foreach($arrObjVars as $key=>$value) { + + //$value=(!is_object($value) && !is_array($value) && trim($value)=="") ? "[empty string]" : $value; + $this->makeTDHeader('object',$key); + + //check for recursion + if(is_object($value)||is_array($value)) { + $var_ser = serialize($value); + if(in_array($var_ser, $this->arrHistory, TRUE)) { + echo (is_object($value)) ? '*RECURSION* -> $'.get_class($value) : '*RECURSION*'; + echo $this->closeTDRow(); + continue; + } + } + //if(in_array(gettype($value),$this->arrType)) + $this->checkType($value); + //else + //echo $value; + echo $this->closeTDRow(); + } + $arrObjMethods=get_class_methods(get_class($var)); + foreach($arrObjMethods as $key=>$value) { + $this->makeTDHeader('object',$value); + echo '[function]'.$this->closeTDRow(); + } + if($var instanceof \Iterator){ + foreach($var as $key=>$value) { + $this->makeTDHeader('array',$key); + $this->checkType($value); + echo $this->closeTDRow(); + } + } + } + else{ + $this->makeTableHeader('object','object'); + echo ''.$this->error('object').$this->closeTDRow(); + } + array_pop($this->arrHistory); + echo ''; + } + + function varIsSpecialObject(&$var){ + if($this->varIsDBObject($var))return 1; + if($var instanceof Exception){ + $this->varIsException($var); + return 1; + } + return 0; + } + + + //!shows info about different resources, uses customized rendering founctions when needed + function varIsResource($var) { + $this->makeTableHeader('resourceC','resource',1); + echo "\n\n"; + $restype=get_resource_type($var); + switch($restype) { + case 'fbsql result': + case 'mssql result': + case 'msql query': + case 'pgsql result': + case 'sybase-db result': + case 'sybase-ct result': + case 'mysql result': + $db=current(explode(' ',$restype)); + $this->varIsDBResource($var,$db); + break; + case 'gd': + $this->varIsGDResource($var); + break; + case 'xml': + $this->varIsXmlResource($var); + break; + case 'curl': + $this->varIsCurlEasyResource($var); + break; + /*case "curl_multi": + $this->varIsCurlMultiResource($var); + break;*/ + default: + echo $restype.$this->closeTDRow(); + break; + } + echo $this->closeTDRow()."\n"; + } + + //!@} + + /*! + @name functions for rendering different resources + */ + //!@{ + + //!shows information about curl easy handles + /*!simply iterates through handle info and displays everything which is not converted into false*/ + function varIsCurlEasyResource(&$var) { + $this->makeTableHeader('resource','curl easy handle',2); + $info=curl_getinfo($var); + foreach($info as $name=>&$piece){ + if($piece){ + $this->makeTDHeader('resource',$name); + //echo $piece.$this->closeTDRow(); + $this->checkType($piece); + echo $this->closeTDRow(); + } + } + unset($info); + echo ''; + + } + //!not implemented yet + function varIsCurlMultiResource(&$var) { + + } + + //!if variable is an image/gd resource type + function varIsGDResource(&$var) { + $this->makeTableHeader('resource','gd',2); + $this->makeTDHeader('resource','Width'); + $this->checkType(imagesx($var)); + echo $this->closeTDRow(); + $this->makeTDHeader('resource','Height'); + $this->checkType(imagesy($var)); + echo $this->closeTDRow(); + $this->makeTDHeader('resource','Colors'); + $this->checkType(imageistruecolor($var)?'TrueColor (16 777 216)':imagecolorstotal($var)); + echo $this->closeTDRow(); + + $this->makeTDHeader('resource','Image'); + + + + ob_start(); + imagepng($var); + $img = ob_get_clean(); + + echo ''.$this->closeTDRow(); + echo ''; + } + + //!@} + + + /*! + @name database results rendering functions + */ + //!@{ + + //!renders either PDO or SQLite3 statement objects + /*!@returns 1 if the object is DB object, 0 otherwise*/ + function varIsDBObject($var) { + $structure=array(); + $data=array(); + $retres=false; + if($var instanceof SQLite3Result){ + //$var=clone $var; + $dbtype=''; + $count=$var->numColumns(); + for($i=0;$i<$count;$i++){ + $structure[$i]=array(); + $structure[$i][0]=$var->columnName($i); + $structure[$i][1]=$var->columnType($i); + } + $var->reset(); + while($res=$var->fetchArray(SQLITE3_NUM)){ + $data[]=$res; + } + $var->reset(); + $dbtype='SQLite3'; + unset($var); + $this->renderDBData($dbtype,$structure,$data); + $retres=true; + } + if($var instanceof PDOStatement){ + //$var=clone $var; + $count=$var->columnCount(); + $col=null; + for($i=0;$i<$count;$i++){ + //$col=$var->getColumnMeta(0); + $col=$var->getColumnMeta($i); + $structure[$i]=array(); + $structure[$i][0]=$col['name']; + $structure[$i][1]=(isset($col['driver:decl_type'])?(isset($col["len"])?"({$col["len"]})":'')."\n":'')."({$col["native_type"]})"; + } + unset($col); + $data=$var->fetchAll(); + $var->closeCursor(); + $dbtype='PDOStatement'; + unset($var); + $this->renderDBData($dbtype,$structure,$data); + $retres=true; + } + unset($dbtype); + unset($data); + unset($structure); + return $retres; + } + + //!renders database data + /*! + @param string $objectType type of the db, it is only the name of header now + @param array $structure 'header' of the table - columns names and types + @param array $data rows of sql request result + */ + function renderDBData(&$objectType,&$structure,&$data){ + $this->makeTableHeader('database',$objectType,count($structure)+1); + echo ' '; + foreach($structure as $field) { + echo ''.$field[0].""; + } + echo ''; + if(empty($data)){ + echo '[empty result]'; + }else + $i=0; + foreach($data as $row) { + echo "\n"; + echo ''.(++$i).''; + for($k=0;$k'.$fieldrow."\n"; + } + echo "\n"; + } + echo ''; + } + + //!renders database resource (fetch result) into table or ... smth else + function varIsDBResource($var,$db='mysql') { + if($db == 'pgsql') + $db = 'pg'; + if($db == 'sybase-db' || $db == 'sybase-ct') + $db = 'sybase'; + $arrFields = array('name','type','flags'); + $numrows=call_user_func($db.'_num_rows',$var); + $numfields=call_user_func($db.'_num_fields',$var); + $this->makeTableHeader('database',$db.' result',$numfields+1); + echo ' '; + for($i=0;$i<$numfields;$i++) { + $field_header = ''; + for($j=0; $j'.$field_name.''; + } + echo ''; + for($i=0;$i<$numrows;$i++) { + $row=call_user_func($db.'_fetch_array',$var,constant(strtoupper($db).'_ASSOC')); + echo "\n"; + echo ''.($i+1).''; + for($k=0;$k<$numfields;$k++) { + $tempField=$field[$k]->name; + $fieldrow=$row[($field[$k]->name)]; + $fieldrow=($fieldrow=='') ? '[empty string]' : $fieldrow; + echo ''.$fieldrow."\n"; + } + echo "\n"; + } + echo ''; + if($numrows>0) + call_user_func($db.'_data_seek',$var,0); + } + //!@} + + + /*! + @name other special kinds of objects rendering functionality + */ + //!@{ + + //!array of properties of every exception to be rendered first + static $exceptionMainProps=array('message','code','file','line'); + //!array of properties of Exception of not to be rendered + static $exceptionExcludedProps=array( + //'xdebug_message', + 'trace' + ); + + //!function used to render exceptions + /*! + Renders exceptions : at first basic fields, then custom fields. + Custom private and protected fields are rendered if reflection api is available + */ + function varIsException(&$var) { + $code=$var->getCode(); + $this->makeTableHeader('Exception',get_class($var).' :: '.$code); + foreach(static::$exceptionMainProps as &$pname) { + $this->makeTDHeader('Exception',$pname); + $this->checkType($var->{'get'.ucfirst($pname)}()); + echo $this->closeTDRow(); + } + unset($pname); + echo ''; + if(extension_loaded('Reflection')){ + $refl=new ReflectionObject($var); + $props=$refl->getProperties(ReflectionProperty::IS_PROTECTED|ReflectionProperty::IS_PRIVATE); + foreach($props as &$prop) { + $pname=$prop->getName(); + if(in_array($pname,static::$exceptionMainProps)||in_array($pname,static::$exceptionExcludedProps))continue; + $this->makeTDHeader('Exception',$pname); + $prop->setAccessible(true); + $this->checkType($prop->getValue($var)); + $prop->setAccessible(false); + echo $this->closeTDRow(); + } + } + + foreach($var as $key=>&$value) { + if($key=='xdebug_message')continue; + $this->makeTDHeader('Exception',$key); + $this->checkType($value); + echo $this->closeTDRow(); + } + + echo ''; + } + + //!@} + + + + /*! + @name xml rendering functions + */ + //!@{ + + //!if variable is an xml type + //!remember, that you must force type to xml to use this + function varIsXml($var) { + $this->varIsXmlResource($var); + } + + //!if variable is an xml resource type + function varIsXmlResource($var) { + $xml_parser=xml_parser_create(); + xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0); + xml_set_element_handler($xml_parser,array(&$this,'xmlStartElement'),array(&$this,'xmlEndElement')); + xml_set_character_data_handler($xml_parser,array(&$this,'xmlCharacterData')); + xml_set_default_handler($xml_parser,array(&$this,'xmlDefaultHandler')); + + $this->makeTableHeader('xml','xml document',2); + $this->makeTDHeader('xml','xmlRoot'); + + //attempt to open xml file + $bFile=(!($fp=@fopen($var,'r'))) ? false : true; + + //read xml file + if($bFile) { + while($data=str_replace("\n",'',fread($fp,4096))) + $this->xmlParse($xml_parser,$data,feof($fp)); + } + //if xml is not a file, attempt to read it as a string + else { + if(!is_string($var)) { + echo $this->error('xml').$this->closeTDRow()."\n"; + return; + } + $data=$var; + $this->xmlParse($xml_parser,$data,1); + } + + echo $this->closeTDRow()."\n"; + + } + + //!parses xml + function xmlParse($xml_parser,$data,$bFinal) { + if (!xml_parse($xml_parser,$data,$bFinal)) { + die(sprintf("XML error: %s at line %d\n", + xml_error_string(xml_get_error_code($xml_parser)), + xml_get_current_line_number($xml_parser))); + } + } + + //!xml: inititiated when a start tag is encountered + function xmlStartElement($parser,$name,$attribs) { + $this->xmlAttrib[$this->xmlCount]=$attribs; + $this->xmlName[$this->xmlCount]=$name; + $this->xmlSData[$this->xmlCount]='$this->makeTableHeader("xml","xml element",2);'; + $this->xmlSData[$this->xmlCount].='$this->makeTDHeader("xml","xmlName");'; + $this->xmlSData[$this->xmlCount].='echo "'.$this->xmlName[$this->xmlCount].'".$this->closeTDRow();'; + $this->xmlSData[$this->xmlCount].='$this->makeTDHeader("xml","xmlAttributes");'; + if(count($attribs)>0) + $this->xmlSData[$this->xmlCount].='$this->varIsArray($this->xmlAttrib['.$this->xmlCount.']);'; + else + $this->xmlSData[$this->xmlCount].='echo " ";'; + $this->xmlSData[$this->xmlCount].='echo $this->closeTDRow();'; + $this->xmlCount++; + } + + //!xml: initiated when an end tag is encountered + function xmlEndElement($parser,$name) { + for($i=0;$i<$this->xmlCount;$i++) { + eval($this->xmlSData[$i]); + $this->makeTDHeader("xml","xmlText"); + echo (!empty($this->xmlCData[$i])) ? $this->xmlCData[$i] : " "; + echo $this->closeTDRow(); + $this->makeTDHeader("xml","xmlComment"); + echo (!empty($this->xmlDData[$i])) ? $this->xmlDData[$i] : " "; + echo $this->closeTDRow(); + $this->makeTDHeader('xml',"xmlChildren"); + unset($this->xmlCData[$i],$this->xmlDData[$i]); + } + echo $this->closeTDRow(); + echo ''; + $this->xmlCount=0; + } + + //!xml: initiated when text between tags is encountered + function xmlCharacterData($parser,$data) { + $count=$this->xmlCount-1; + if(!empty($this->xmlCData[$count])) + $this->xmlCData[$count].=$data; + else + $this->xmlCData[$count]=$data; + } + + //!@} + + //!xml: initiated when a comment or other miscellaneous texts is encountered + function xmlDefaultHandler($parser,$data) { + //strip '' off comments + $data=str_replace(array("<!--","-->"),"",htmlspecialchars($data)); + $count=$this->xmlCount-1; + if(!empty($this->xmlDData[$count])) + $this->xmlDData[$count].=$data; + else + $this->xmlDData[$count]=$data; + } + + //! adds needed JS and CSS sources to page + static function initJSandCSS() { + echo << + /* code modified from ColdFusion's cfdump code */ + function dBug_toggleRow(source) { + var target = (document.all) ? source.parentElement.cells[1] : source.parentNode.lastChild; + dBug_toggleTarget(target,dBug_toggleSource(source)); + } + + function dBug_toggleSource(source) { + if (source.style.fontStyle=='italic') { + source.style.fontStyle='normal'; + source.title='click to collapse'; + return 'open'; + } else { + source.style.fontStyle='italic'; + source.title='click to expand'; + return 'closed'; + } + } + + function dBug_toggleTarget(target,switchToState) { + target.style.display = (switchToState=='open') ? '' : 'none'; + } + + function dBug_toggleTable(source) { + var switchToState=dBug_toggleSource(source); + if(document.all) { + var table=source.parentElement.parentElement; + for(var i=1;i + + +SCRIPTS; + } +} \ No newline at end of file