PHP Classes

File: src/Processors/ObjectProcessor.php

Recommend this page to a friend!
  Classes of Rodolfo Berrios Arce   Var-Dump   src/Processors/ObjectProcessor.php   Download  
File: src/Processors/ObjectProcessor.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Var-Dump
Show the value of a variable in colored way
Author: By
Last change:
Date: 1 month ago
Size: 6,721 bytes
 

Contents

Class file image Download
<?php

/*
 * This file is part of Chevere.
 *
 * (c) Rodolfo Berrios <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace
Chevere\VarDump\Processors;

use
Chevere\Parameter\Interfaces\TypeInterface;
use
Chevere\VarDump\Interfaces\ProcessorInterface;
use
Chevere\VarDump\Interfaces\ProcessorNestedInterface;
use
Chevere\VarDump\Interfaces\VarDumperInterface;
use
Chevere\VarDump\Processors\Traits\HandleDepthTrait;
use
Chevere\VarDump\Processors\Traits\ProcessorTrait;
use
Reflection;
use
ReflectionObject;

final class
ObjectProcessor implements ProcessorInterface, ProcessorNestedInterface
{
    use
ProcessorTrait;
    use
HandleDepthTrait;

    private
object $var;

    private
string $className;

    private
int $objectId;

    public function
__construct(
        private
VarDumperInterface $varDumper
   
) {
       
$this->assertType();
       
/** @var object $object */
       
$object = $this->varDumper->dumpable()->var();
       
$this->var = $object;
       
$this->depth = $this->varDumper->depth() + 1;
       
$this->className = $this->var::class;
       
$this->handleNormalizeClassName();
       
$this->objectId = spl_object_id($this->var);
       
$this->info = $this->className . '#' . $this->objectId;
    }

    public function
type(): string
   
{
        return
TypeInterface::OBJECT;
    }

    public function
write(): void
   
{
       
$this->varDumper->writer()->write(
           
$this->varDumper->format()
                ->
highlight(
                   
VarDumperInterface::CLASS_REG,
                   
$this->className
               
)
            .
           
$this->varDumper->format()
                ->
highlight(
                   
VarDumperInterface::OPERATOR,
                   
'#' . strval($this->objectId)
                )
        );
        if (
$this->varDumper->objectReferences()->has($this->objectId)) {
           
$this->varDumper->writer()->write(
                <<<STRING
{$this->highlightParentheses(
                   
$this->circularReference() . ' #' . $this->objectId
               
)}
STRING
            );

            return;
        }
       
$this->varDumper->objectReferences()->push($this->objectId);
        if (
$this->depth > self::MAX_DEPTH) {
           
$this->varDumper->writer()->write(
                <<<STRING
{$this->highlightParentheses($this->maxDepthReached())}
STRING
            );

            return;
        }
       
$this->setProperties($this->var);
    }

    private function
setProperties(object $object): void
   
{
       
$reflection = new ReflectionObject($object);
       
$properties = [];
       
$properties = $this->getProperties($object, $reflection);
       
// @codeCoverageIgnoreStart
       
if ($properties === [] && $reflection->isInternal()) {
           
$properties = $this->getPublicProperties();
        }
       
// @codeCoverageIgnoreEnd
       
$keys = array_keys($properties);
       
$aux = 0;
        foreach (
$keys as $name) {
           
$aux++;
           
$name = strval($name);
           
/** @var string[] */
           
$property = $properties[$name];
           
$property[] = $aux;
           
// @phpstan-ignore-next-line
           
$this->processProperty($name, ...$property);
        }
        if (
$aux > 0) {
           
$this->varDumper->writer()->write(
               
$this->varDumper->format()->detailsClose()
            );
        }
    }

   
/**
     * @return array<string, array<mixed>>
     * @codeCoverageIgnore
     */
   
private function getPublicProperties(): array
    {
       
/** @var array<string, array<mixed>> $properties */
       
$properties = json_decode(json_encode($this->var) ?: '', true) ?? [];
        foreach (
$properties as $name => $value) {
           
$name = strval($name);
           
$properties[$name] = ['public', $value, false];
        }

        return
$properties;
    }

   
/**
     * @return array<string, array<mixed>>
     */
   
private function getProperties(
       
object $object,
       
ReflectionObject $reflection
   
): array {
       
$properties = [];
        do {
            foreach (
$reflection->getProperties() as $property) {
                if (
$property->isStatic()) {
                    continue;
                }
               
$isUnset = false;
                if (!
$property->isInitialized($object)) {
                   
$value = '';
                   
$isUnset = true;
                } else {
                   
$value = $property->getValue($this->var);
                }
               
$properties[$property->getName()] = [
                   
implode(
                       
' ',
                       
Reflection::getModifierNames($property->getModifiers())
                    ),
                   
$value ?? null,
                   
$isUnset,
                ];
            }
        } while (
$reflection = $reflection->getParentClass());

        return
$properties;
    }

    private function
processProperty(
       
string $name,
       
string $modifier,
       
mixed $value,
       
bool $isUnset,
       
int $aux
   
): void {
        if (
$aux === 1) {
           
$this->varDumper->writer()->write(
               
$this->varDumper->format()->detailsOpen(
                   
$this->varDumper->depth() === 0
               
)
            );
            if (
$this->varDumper->format()->detailsClose() === '') {
               
$this->varDumper->writer()->write("\n");
            }
        } else {
           
$this->varDumper->writer()->write("\n");
        }
       
$indentString = $this->varDumper->indentString();
       
$modifier = $this->varDumper->format()->highlight(
           
VarDumperInterface::MODIFIER,
           
$modifier
       
);
       
$variable = $this->varDumper->format()->highlight(
           
VarDumperInterface::VARIABLE,
           
$this->varDumper->format()->filterEncodedChars($name)
        );
       
$this->varDumper->writer()->write(
           
" {$indentString}{$modifier} {$variable} "
       
);
        if (
$isUnset) {
           
$unset = $this->varDumper->format()->highlight(
               
VarDumperInterface::EMPHASIS,
               
'uninitialized'
           
);
           
$this->varDumper->writer()->write($unset);
        } else {
           
$this->handleDepth($value);
        }
    }

    private function
handleNormalizeClassName(): void
   
{
        if (
str_starts_with($this->className, VarDumperInterface::CLASS_ANON)) {
           
$this->className = VarDumperInterface::CLASS_ANON;
        }
    }
}