<?php
/**
 * Based on
 * TVarDumper class file
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link https://github.com/pradosoft/prado
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
 */
namespace CMSMSExt\core;

  /**
   * VarDumper class.
   *
   * VarDumper is intended to replace the buggy PHP function var_dump and print_r.
   * It can correctly identify the recursively referenced objects in a complex
   * object structure. It also has a recursive depth control to avoid indefinite
   * recursive display of some peculiar variables.
   *
   * VarDumper can be used as follows,
   * <code>
   *   echo VarDumper::dump($var);
   * </code>
   *
   * @author Qiang Xue <qiang.xue@gmail.com>
   * @since 3.0
   */
class VarDumper
{
  private static $_objects;
  private static $_output;
  private static $_depth;
  
  /**
   * Converts a variable into a string representation.
   * This method achieves the similar functionality as var_dump and print_r
   * but is more robust when handling complex objects such as PRADO controls.
   * @param mixed $var variable to be dumped
   * @param int $depth maximum depth that the dumper should go into the variable. Defaults to 10.
   * @param bool $highlight whether to highlight the resulting string
   * @return string the string representation of the variable
   */
  public static function dump($var, $depth = 10, $highlight = false)
  {
    self::$_output = '';
    self::$_objects = [];
    self::$_depth = $depth;
    self::dumpInternal($var, 0);
    
    if($highlight)
    {
      $result = highlight_string("<?php\n" . self::$_output, TRUE);
      
      return preg_replace('/&lt;\\?php<br \\/>/', '', $result, 1);
    }
    else
    {
      return self::$_output;
    }
  }
  
  private static function dumpInternal($var, $level)
  {
    switch (gettype($var)) {
      case 'boolean':
        self::$_output .= $var ? 'true' : 'false';
      break;
      case 'integer':
        self::$_output .= "$var";
      break;
      case 'double':
        self::$_output .= "$var";
      break;
      case 'string':
        self::$_output .= "'$var'";
      break;
      case 'resource':
        self::$_output .= '{resource}';
      break;
      case 'NULL':
        self::$_output .= "null";
      break;
      case 'unknown type':
        self::$_output .= '{unknown}';
      break;
      case 'array':
        if (self::$_depth <= $level) {
          self::$_output .= 'array(...)';
        } elseif (empty($var)) {
          self::$_output .= 'array()';
        } else {
          $keys = array_keys($var);
          $spaces = str_repeat(' ', $level * 4);
          self::$_output .= "array\n" . $spaces . '(';
          foreach ($keys as $key) {
            self::$_output .= "\n" . $spaces . "    [$key] => ";
            self::$_output .= self::dumpInternal($var[$key], $level + 1);
          }
          self::$_output .= "\n" . $spaces . ')';
        }
      break;
      case 'object':
        if (($id = array_search($var, self::$_objects, true)) !== false) {
          self::$_output .= get_class($var) . '#' . ($id + 1) . '(...)';
        } elseif (self::$_depth <= $level) {
          self::$_output .= get_class($var) . '(...)';
        } else {
          $id = array_push(self::$_objects, $var);
          $className = get_class($var);
          $members = (array) $var;
          $keys = array_keys($members);
          $spaces = str_repeat(' ', $level * 4);
          self::$_output .= "$className#$id\n" . $spaces . '(';
          foreach ($keys as $key) {
            $keyDisplay = strtr(trim($key), ["\0" => ':']);
            self::$_output .= "\n" . $spaces . "    [$keyDisplay] => ";
            self::$_output .= self::dumpInternal($members[$key], $level + 1);
          }
          self::$_output .= "\n" . $spaces . ')';
        }
      break;
    }
  }
}
?>