* @copyright copyright @ by Dick Munroe, 2004 * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @package StructuredDataDumper * @version 1.0.4 */ // // Edit History: // // Dick Munroe munroe@cworks.com 04-Dec-2004 // Initial version created. // // Dick Munroe munroe@csworks.com 08-Dec-2004 // Translate < to < for html output. // // Dick Munroe munroe@csworks.com 23-Dec-2004 // Add interface for writing "stuff". Extend SDD // to get things "written". // // Dick Munroe munroe@csworks.com 25-Dec-2004 // If a class extends a base class, but doesn't add // data members, a warning winds up appearing when // printing. // Added a memeber to fetch the state of the logging // flag. // // Dick Munroe munroe@csworks.com 11-Mar-2006 // The test for html flag should have assumed that // $this can be defined for objects calling SDD::dump. // // Dick Munroe (munroe@csworks.com) 22-Mar-2006 // Add a function to generate "newlines". // class SDD { /** * HTML to be generated flag. */ var $m_htmlFlag ; /** * logging flag. */ var $m_logging = false ; /** * In memory log file. */ var $m_log = array() ; /** * Constructor. * * @access public * @param boolean $theHTMLFlag [optional] True if HTML is to be generated. * If omitted, $_SERVER is used to "guess" the state of * the HTML flag. Be default, HTML is generated when * accessed by a web server. * @param boolean $theLoggingFlag [optional] the state of logging for * this object. By default, logging is off. */ function SDD($theHtmlFlag=null, $theLoggingFlag=false) { if ($theHtmlFlag === null) { $theHtmlFlag = (!empty($_SERVER['DOCUMENT_ROOT'])) ; } $this->m_htmlFlag = $theHtmlFlag ; $this->m_logging = $theLoggingFlag ; } /** * Close the log file. * * @access public * @abstract */ function close() { } /** * Dump a structured variable. * * @static * @param mixed $theVariable the variable to be dumped. * @param boolean $theHtmlFlag [optional] true if HTML is to be generated, * false if plain text is to be generated, null (default) if * dump is to guess which to display. * @return string The data to be displayed. * @link http://www.php.net/manual/en/reserved.variables.php#reserved.variables.server Uses $_SERVER */ function dump(&$theVariable, $theHtmlFlag=null) { if ($theHtmlFlag === null) { if (empty($this)) { $theHtmlFlag = (!empty($_SERVER['DOCUMENT_ROOT'])) ; } else { if (is_subclass_of($this, "sdd")) { $theHtmlFlag = $this->m_htmlFlag ; } else { $theHtmlFlag = (!empty($_SERVER['DOCUMENT_ROOT'])) ; } } } switch (gettype($theVariable)) { case 'array': { return SDD::dArray($theVariable, $theHtmlFlag) ; } case 'object': { return SDD::dObject($theVariable, $theHtmlFlag) ; } default: { return SDD::scalar($theVariable, $theHtmlFlag) ; } } } /** * Dump the contents of an array. * * @param array $theArray the array whose contents are to be displayed. * @param boolean $theHTMLFlag True if an HTML table is to be generated, * false otherwise. * @param string $theIndent [optional] Used by SDD::dArray during recursion * to get indenting right. * @return string The display form of the array. */ function dArray(&$theArray, $theHTMLFlag, $theIndent = "") { $theOutput = array() ; foreach($theArray as $theIndex => $theValue) { if (is_array($theValue)) { $theString = SDD::dArray($theValue, $theHTMLFlag, $theIndent . " ") ; $theOutput[$theIndex] = substr($theString, 0, strlen($theString) - 1) ; } else if (is_object($theValue)) { $theOutput[$theIndex] = SDD::dObject($theValue, $theHTMLFlag) ; } else { $theOutput[$theIndex] = ($theHTMLFlag ? preg_replace('|<|s', '<', var_export($theValue, true)) : var_export($theValue, true)) ; } } if ($theHTMLFlag) { $theString = "\n" ; $theString .= "\n" ; foreach ($theOutput as $theIndex => $theVariableOutput) { $theString .= "\n\n\n" ; } $theString .= "\n" ; $theString .= "
Array (
$theIndex = >\n$theVariableOutput\n
)
\n" ; } else { $theString = "Array\n$theIndent(\n" ; foreach ($theOutput as $theIndex => $theVariableOutput) { $theString .= "$theIndent [$theIndex] => " . $theVariableOutput . "\n" ; } $theString .= "$theIndent)\n" ; } return $theString ; } /** * Dump the contents of an object. * * Provide a structured display of an object and all the * classes from which it was derived. The contents of * the object is displayed from most derived to the base * class, in order. * * @param object $theObject the object to be dumped. * @param boolean $theHTMLFlag true if HTML is to be generated. * @return string the display form of the object. */ function dObject(&$theObject, $theHTMLFlag) { $theObjectVars = get_object_vars($theObject) ; // // Get the inheritance tree starting with the object and going // through all the parent classes from there. // $theClass = get_class($theObject) ; $theClasses[] = $theClass ; while ($theClass = get_parent_class($theClass)) { $theClasses[] = $theClass ; } // // Get all the class variables for each class in the inheritance // tree. There will be some duplication, but we'll sort that out // in the output process. // foreach($theClasses as $theClass) { $theClassVars[$theClass] = get_class_vars($theClass) ; } // // Put the inheritance tree from base class to most derived order // (this is how we get rid of duplication of the variable names) // Go through the object variables starting with the base class, // capture the output and delete the variable from the object // variables. // $theClasses = array_reverse($theClasses) ; $theOutput = array() ; foreach ($theClasses as $theClass) { $theOutput[$theClass] = array() ; foreach ($theClassVars[$theClass] as $theVariable => $value) { if (array_key_exists($theVariable, $theObjectVars)) { if (is_array($theObjectVars[$theVariable])) { $theOutput[$theClass][] = $theVariable . " = " . SDD::dArray($theObjectVars[$theVariable], $theHTMLFlag) ; } else if (is_object($theObjectVars[$theVariable])) { $theOutput[$theClass][] = $theVariable . " = " . SDD::dObject($theObjectVars[$theVariable], $theHTMLFlag) ; } else { $theOutput[$theClass][] = $theVariable . " = " . ($theHTMLFlag ? preg_replace('|<|s', '<', var_export($theObjectVars[$theVariable], true)) : var_export($theObjectVars[$theVariable], true)) ; } unset($theObjectVars[$theVariable]) ; } } } // // Put the classes back in most derived order for generating printable // output. // $theClasses = array_reverse($theClasses) ; if ($theHTMLFlag) { $theString = "\n\n" ; foreach ($theClasses as $theClass) { $theString .= "\n" ; } $theString .= "\n\n" ; foreach ($theClasses as $theClass) { $theString .= "\n" ; } $theString .= "\n
\n$theClass\n
\n\n" ; foreach ($theOutput[$theClass] as $theVariableOutput) { $theString .= "\n\n\n" ; } $theString .= "
\n$theVariableOutput\n
\n
\n" ; } else { $classIndent = "" ; $classDataIndent = " " ; $theString = "" ; foreach ($theClasses as $theClass) { $theString .= "{$classIndent}class $theClass\n\n" ; foreach ($theOutput[$theClass] as $theVariableOutput) { $theString .= "$classDataIndent$theVariableOutput\n" ; } $theString .= "\n" ; $classIndent .= " " ; $classDataIndent .= " " ; } } return $theString ; } /** * Write a debugging value to a log file. * * @access public * @abstract * @param mixed Data to be logged. * @param string $theHeader [optional] string to be emitted prior to * logging the data. By default it is a date/time * stamp. */ function log(&$theData, $theHeader=null) { $theHeader = date('[Y-m-d H:i:s]: ') . $theHeader ; if ($this->m_logging) { if ($this->m_htmlFlag) { $xxx = $this->dump($theData) ; if (substr($xxx, 0, 5) == '
')
                {
                  $xxx = '
' . $theHeader . substr($xxx, 5) ;
                }
              else
                {
                  $xxx = $theHeader . $xxx ;
                }

              $this->writeLog($xxx) ;
            }
          else
            {
              $xxx = $theHeader . $this->dump($theData) ;
              $this->writeLog($xxx) ;
            }
        }
    }

  /**
   * @desc Generate context specific new line equivalents.
   * @param integer [optional] the number of newlines.
   * @param boolean [optional] true if generating html newlines.
   * @return string newlines.
   * @access public
   */
   
  function newline($theCount=1, $theHtmlFlag=null)
    {
      if ($theHtmlFlag === null)
        {
          if (empty($this))
            {
              $theHtmlFlag = (!empty($_SERVER['DOCUMENT_ROOT'])) ;
            }
          else
            {
              if (is_subclass_of($this, "sdd"))
              {
                $theHtmlFlag = $this->m_htmlFlag ;
              }
              else
              {
                $theHtmlFlag = (!empty($_SERVER['DOCUMENT_ROOT'])) ;
              }
            }
        }
       
      if ($theHtmlFlag)
        {
          return str_repeat("
", max($theCount, 0)) . "\n" ; } else { return str_repeat("\n", max($theCount, 0)) ; } } /** * Dump any scalar value * * @param mixed $theVariable the variable to be dumped. * @param boolean $theHtmlFlag true if html is to be generated. */ function scalar(&$theVariable, $theHtmlFlag) { if ($theHtmlFlag) { return "
" . preg_replace('|<|s', '<', var_export($theVariable, true)) . "
" ; } else { return var_export($theVariable, true) ; } } /** * Write data to the log file. * * @access public * @abstract * @parameter string $theData [by reference] the data to be written * into the log file. * @return integer the number of bytes written into the log file. */ function writeLog(&$theData) { return strlen($this->m_log[] = $theData) ; } /** * Return the state of the logging flag. * * @access public * @return boolean */ function getLogging() { return $this->m_logging ; } /** * Set the state of the logging flag. * * @access public * @return boolean */ function setLogging($theLogging=false) { $this->m_logging = $theLogging ; } } ?>