You are here

private static function kintParser::_parse_object in Devel 8.2

Same name and namespace in other branches
  1. 8 kint/kint/inc/kintParser.class.php \kintParser::_parse_object()

File

kint/kint/inc/kintParser.class.php, line 405

Class

kintParser

Code

private static function _parse_object(&$variable, kintVariableData $variableData) {
  if (function_exists('spl_object_hash')) {
    $hash = spl_object_hash($variable);
  }
  else {
    ob_start();
    var_dump($variable);
    preg_match('[#(\\d+)]', ob_get_clean(), $match);
    $hash = $match[1];
  }
  $castedArray = (array) $variable;
  $variableData->type = get_class($variable);
  $variableData->size = count($castedArray);
  if (isset(self::$_objects[$hash])) {
    $variableData->value = '*RECURSION*';
    return false;
  }
  if (self::_checkDepth()) {
    $variableData->extendedValue = "*DEPTH TOO GREAT*";
    return false;
  }

  # ArrayObject (and maybe ArrayIterator, did not try yet) unsurprisingly consist of mainly dark magic.

  # What bothers me most, var_dump sees no problem with it, and ArrayObject also uses a custom,

  # undocumented serialize function, so you can see the properties in internal functions, but

  # can never iterate some of them if the flags are not STD_PROP_LIST. Fun stuff.
  if ($variableData->type === 'ArrayObject' || is_subclass_of($variable, 'ArrayObject')) {
    $arrayObjectFlags = $variable
      ->getFlags();
    $variable
      ->setFlags(ArrayObject::STD_PROP_LIST);
  }
  self::$_objects[$hash] = true;

  // todo store reflectorObject here for alternatives cache
  $reflector = new ReflectionObject($variable);

  # add link to definition of userland objects
  if (Kint::enabled() === Kint::MODE_RICH && Kint::$fileLinkFormat && $reflector
    ->isUserDefined()) {
    $url = Kint::getIdeLink($reflector
      ->getFileName(), $reflector
      ->getStartLine());
    $class = strpos($url, 'http://') === 0 ? 'class="kint-ide-link" ' : '';
    $variableData->type = "<a {$class}href=\"{$url}\">{$variableData->type}</a>";
  }
  $variableData->size = 0;
  $extendedValue = array();
  $encountered = array();

  # copy the object as an array as it provides more info than Reflection (depends)
  foreach ($castedArray as $key => $value) {

    /* casting object to array:
     * integer properties are inaccessible;
     * private variables have the class name prepended to the variable name;
     * protected variables have a '*' prepended to the variable name.
     * These prepended values have null bytes on either side.
     * http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
     */
    if ($key[0] === "\0") {
      $access = $key[1] === "*" ? "protected" : "private";

      // Remove the access level from the variable name
      $key = substr($key, strrpos($key, "\0") + 1);
    }
    else {
      $access = "public";
    }
    $encountered[$key] = true;
    $output = kintParser::factory($value, self::escape($key));
    $output->access = $access;
    $output->operator = '->';
    $extendedValue[] = $output;
    $variableData->size++;
  }
  foreach ($reflector
    ->getProperties() as $property) {
    $name = $property->name;
    if ($property
      ->isStatic() || isset($encountered[$name])) {
      continue;
    }
    if ($property
      ->isProtected()) {
      $property
        ->setAccessible(true);
      $access = "protected";
    }
    elseif ($property
      ->isPrivate()) {
      $property
        ->setAccessible(true);
      $access = "private";
    }
    else {
      $access = "public";
    }
    $value = $property
      ->getValue($variable);
    $output = kintParser::factory($value, self::escape($name));
    $output->access = $access;
    $output->operator = '->';
    $extendedValue[] = $output;
    $variableData->size++;
  }
  if (isset($arrayObjectFlags)) {
    $variable
      ->setFlags($arrayObjectFlags);
  }
  if ($variableData->size) {
    $variableData->extendedValue = $extendedValue;
  }
}