Files
michaelschiemer/src/Framework/Display
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00
..

Display Module

A comprehensive data formatting and display module for the Framework, supporting both Console and HTML output formats. The module provides intelligent formatting for arrays, objects, classes, filesystem structures, and various data formats (JSON, YAML, XML, CSV).

Table of Contents

Introduction

The Display module provides a unified interface for formatting and displaying various data types in both console and HTML environments. It automatically detects data types and applies appropriate formatting, making it easy to display complex data structures in a readable format.

Key Features

  • Multi-Format Support: Console (ANSI colors) and HTML (semantic HTML/CSS)
  • Auto-Detection: Automatically selects the appropriate formatter based on data type
  • Smart Filtering: Configurable rules for handling large structures and blacklisted classes
  • Collection Detection: Automatically detects and compactly displays collection objects
  • Circular Reference Detection: Prevents infinite loops when displaying object graphs
  • Value Object Support: Special formatting for Value Objects with custom formatters
  • Multiple Data Formats: Support for JSON, YAML, XML, CSV, arrays, objects, classes, and filesystem structures

Quick Start

Basic Usage

use App\Framework\Display\Formatters\AutoFormatter;
use App\Framework\Display\ValueObjects\DisplayOptions;
use App\Framework\Display\ValueObjects\OutputFormat;

$formatter = new AutoFormatter();

// Format for console
$output = $formatter->formatForConsole($data);

// Format for HTML
$output = $formatter->formatForHtml($data);

// With custom options
$options = DisplayOptions::default()
    ->withMaxDepth(5)
    ->withCompactValueObjects(true);

$output = $formatter->format($data, $options, OutputFormat::CONSOLE);

Formatting Different Data Types

$formatter = new AutoFormatter();

// Arrays
$array = ['name' => 'John', 'age' => 30, 'city' => 'Berlin'];
echo $formatter->formatForConsole($array);

// Objects
$object = new User(name: 'John', age: 30);
echo $formatter->formatForConsole($object);

// JSON strings
$json = '{"name":"John","age":30}';
echo $formatter->formatForConsole($json);

// YAML strings
$yaml = "name: John\nage: 30";
echo $formatter->formatForConsole($yaml);

// XML strings
$xml = '<user><name>John</name><age>30</age></user>';
echo $formatter->formatForConsole($xml);

// CSV strings
$csv = "name,age\nJohn,30\nJane,25";
echo $formatter->formatForConsole($csv);

// Classes
echo $formatter->formatForConsole(User::class);

// Filesystem directories
echo $formatter->formatForConsole('/path/to/directory');

Architecture Overview

The Display module follows a three-layer architecture:

1. Inspectors

Inspectors analyze raw data and create normalized Value Objects:

  • ArrayInspector: Analyzes arrays and creates ArrayStructure
  • ObjectInspector: Analyzes objects and creates ObjectStructure
  • ClassInspector: Analyzes classes and creates ClassStructure
  • FilesystemInspector: Analyzes filesystem structures and creates DirectoryStructure

2. Renderers

Renderers take normalized Value Objects and render them into the target output format:

  • ConsoleRenderer: Renders structures for console output with ANSI colors
  • HtmlRenderer: Renders structures for HTML output with semantic HTML/CSS

3. Formatters

Formatters provide high-level APIs combining inspectors and renderers:

  • AutoFormatter: Automatically detects data type and selects appropriate formatter
  • ArrayFormatter: Formats arrays
  • ObjectFormatter: Formats objects
  • ClassFormatter: Formats classes
  • FilesystemFormatter: Formats filesystem structures
  • JsonFormatter: Formats JSON strings
  • YamlFormatter: Formats YAML strings
  • XmlFormatter: Formats XML strings
  • CsvFormatter: Formats CSV strings

Formatters

AutoFormatter

The AutoFormatter automatically detects the input data type and selects the appropriate formatter:

$formatter = new AutoFormatter();

// Automatically detects and formats:
// - Arrays → ArrayFormatter
// - Objects → ObjectFormatter
// - JSON strings → JsonFormatter
// - YAML strings → YamlFormatter
// - XML strings → XmlFormatter
// - CSV strings → CsvFormatter
// - Class names → ClassFormatter
// - Directory paths → FilesystemFormatter
// - Scalars → Scalar formatting

$output = $formatter->formatForConsole($data);

ArrayFormatter

Formats arrays with tree, table, or flat display styles:

use App\Framework\Display\Formatters\ArrayFormatter;
use App\Framework\Display\ValueObjects\DisplayOptions;
use App\Framework\Display\ValueObjects\OutputFormat;

$formatter = new ArrayFormatter();

// Tree style (default)
$options = DisplayOptions::default();
$output = $formatter->format($array, $options, OutputFormat::CONSOLE);

// Table style
$options = DisplayOptions::default()->withFormatStyle('table');
$output = $formatter->format($array, $options, OutputFormat::CONSOLE);

// Flat style
$options = DisplayOptions::default()->withFormatStyle('flat');
$output = $formatter->format($array, $options, OutputFormat::CONSOLE);

ObjectFormatter

Formats objects with property inspection:

use App\Framework\Display\Formatters\ObjectFormatter;

$formatter = new ObjectFormatter();

// Show private/protected properties
$options = DisplayOptions::default()->withShowPrivateProperties(true);
$output = $formatter->formatForConsole($object, $options);

JsonFormatter

Formats JSON strings with syntax highlighting:

use App\Framework\Display\Formatters\JsonFormatter;

$formatter = new JsonFormatter();
$json = '{"name":"John","age":30,"active":true}';

// Console output with ANSI colors
$output = $formatter->formatForConsole($json);

// HTML output with CSS classes
$output = $formatter->formatForHtml($json);

YamlFormatter

Formats YAML strings with syntax highlighting:

use App\Framework\Display\Formatters\YamlFormatter;

$formatter = new YamlFormatter();
$yaml = "name: John\nage: 30\nactive: true";

$output = $formatter->formatForConsole($yaml);

XmlFormatter

Formats XML strings with syntax highlighting:

use App\Framework\Display\Formatters\XmlFormatter;

$formatter = new XmlFormatter();
$xml = '<user><name>John</name><age>30</age></user>';

$output = $formatter->formatForConsole($xml);

CsvFormatter

Formats CSV strings as tables:

use App\Framework\Display\Formatters\CsvFormatter;

$formatter = new CsvFormatter();
$csv = "name,age\nJohn,30\nJane,25";

// Console output as table
$output = $formatter->formatForConsole($csv);

// HTML output as HTML table
$output = $formatter->formatForHtml($csv);

Configuration

DisplayOptions

DisplayOptions controls how data is displayed:

use App\Framework\Display\ValueObjects\DisplayOptions;

// Default options
$options = DisplayOptions::default();

// Compact mode
$options = DisplayOptions::compact(); // maxDepth: 3, no metadata

// Verbose mode
$options = DisplayOptions::verbose(); // maxDepth: 20, show all properties

// Custom options
$options = DisplayOptions::default()
    ->withMaxDepth(5)                    // Maximum nesting depth
    ->withFormatStyle('tree')            // 'tree', 'table', or 'flat'
    ->withShowPrivateProperties(true)     // Show private/protected properties
    ->withCompactValueObjects(true)       // Compact Value Object display
    ->withShowValueObjectType(true)       // Show Value Object type comments
    ->withIndentSize(2)                  // Indentation size
    ->withPrettyPrint(true);              // Pretty print output

DisplayRules

DisplayRules controls filtering and performance optimizations:

use App\Framework\Display\ValueObjects\DisplayRules;
use App\Framework\Display\ValueObjects\DisplayOptions;

// Default rules
$rules = DisplayRules::default();

// Custom rules
$rules = DisplayRules::default()
    ->withBlacklistedClasses([
        'App\\Framework\\DI\\DefaultContainer',
        'App\\Framework\\Discovery\\DiscoveryRegistry',
    ])
    ->withMaxArraySizeForSummary(1000)        // Root arrays > 1000 show summary
    ->withMaxArraySizeForSummaryNested(100)   // Nested arrays > 100 show summary
    ->withMaxObjectPropertiesForSummary(50)   // Root objects > 50 properties show summary
    ->withMaxObjectPropertiesForSummaryNested(20) // Nested objects > 20 properties show summary
    ->withMaxItems(100)                       // Max items before truncation
    ->withCollectionDetection(true)            // Enable collection detection
    ->withCompactNestedObjects(true);         // Compact display for nested objects

$options = DisplayOptions::default()->withRules($rules);

Value Object Formatting

The Display module provides special formatting for Value Objects. Value Objects are automatically detected and can be displayed compactly or with custom formatters.

Automatic Value Object Detection

Value Objects are detected based on:

  • Namespace containing "ValueObjects"
  • Implements Stringable interface
  • Has toString() method
  • final readonly class pattern with limited public methods

Compact Value Object Display

By default, Value Objects are displayed compactly:

$options = DisplayOptions::default()
    ->withCompactValueObjects(true)      // Enable compact display
    ->withShowValueObjectType(true);      // Show type comment

// Value Objects will be displayed as:
// ClassName(value) // ClassName

Custom Value Object Formatters

Create custom formatters for specific Value Objects:

use App\Framework\Display\ValueObjectFormatters\ValueObjectFormatterInterface;
use App\Framework\Display\ValueObjects\DisplayOptions;
use App\Framework\Display\ValueObjects\OutputFormat;

final readonly class CustomValueObjectFormatter implements ValueObjectFormatterInterface
{
    public function supports(object $valueObject): bool
    {
        return $valueObject instanceof CustomValueObject;
    }

    public function format(object $valueObject, DisplayOptions $options, OutputFormat $outputFormat): string
    {
        if (! $valueObject instanceof CustomValueObject) {
            return (string) $valueObject;
        }

        return match ($outputFormat) {
            OutputFormat::CONSOLE => $this->formatConsole($valueObject, $options),
            OutputFormat::HTML => $this->formatHtml($valueObject, $options),
        };
    }

    private function formatConsole(CustomValueObject $vo, DisplayOptions $options): string
    {
        // Custom console formatting
        return ConsoleStyle::create(color: ConsoleColor::GREEN)
            ->apply($vo->toString());
    }

    private function formatHtml(CustomValueObject $vo, DisplayOptions $options): string
    {
        // Custom HTML formatting
        return '<span class="custom-vo">' . htmlspecialchars($vo->toString()) . '</span>';
    }
}

// Register the formatter
$registry = new ValueObjectFormatterRegistry();
$registry->register(new CustomValueObjectFormatter());

// Use with renderers
$renderer = new ConsoleRenderer($registry);

Advanced Usage

Circular Reference Detection

The module automatically detects and handles circular references:

class A {
    public B $b;
}

class B {
    public A $a;
}

$a = new A();
$b = new B();
$a->b = $b;
$b->a = $a;

// Circular references are displayed as [circular reference]
$formatter = new AutoFormatter();
echo $formatter->formatForConsole($a);

Collection Detection

Objects implementing IteratorAggregate and Countable are automatically detected as collections:

class UserCollection implements IteratorAggregate, Countable
{
    private array $users = [];

    public function getIterator(): ArrayIterator
    {
        return new ArrayIterator($this->users);
    }

    public function count(): int
    {
        return count($this->users);
    }
}

// Collections are displayed as:
// UserCollection (75 User objects)

Summary Views for Large Structures

Large arrays and objects are automatically summarized:

// Large array (> 1000 items for root, > 100 for nested)
// Displays as: [array: 10000 items, types: string(60%), int(30%), object(10%)]

// Large object (> 50 properties for root, > 20 for nested)
// Displays as: ClassName [summary: 150 properties, types: string(40), array(30), object(80)]

Blacklist Support

Blacklisted classes are never fully displayed:

$rules = DisplayRules::default()
    ->withBlacklistedClasses([
        'App\\Framework\\DI\\DefaultContainer',
        'App\\Framework\\Discovery\\DiscoveryRegistry',
    ]);

$options = DisplayOptions::default()->withRules($rules);

// Blacklisted objects are displayed as:
// ClassName [blacklisted]

Performance Tips

  1. Use Summary Views: Configure DisplayRules to show summaries for large structures
  2. Limit Depth: Use withMaxDepth() to limit nesting depth
  3. Compact Value Objects: Enable compactValueObjects for better performance
  4. Blacklist Large Objects: Add large objects to blacklist to prevent inspection
  5. Use Collection Detection: Collections are displayed compactly without full inspection

Examples

Console Command Integration

use App\Framework\Display\Formatters\AutoFormatter;
use App\Framework\Console\ConsoleCommand;

#[ConsoleCommand('display:show')]
final class DisplayShowCommand
{
    public function __construct(
        private AutoFormatter $formatter
    ) {}

    public function handle(array $data): void
    {
        $output = $this->formatter->formatForConsole($data);
        echo $output . "\n";
    }
}

Web View Integration

use App\Framework\Display\Formatters\AutoFormatter;
use App\Framework\Display\ValueObjects\OutputFormat;

class DebugController
{
    public function __construct(
        private AutoFormatter $formatter
    ) {}

    public function showData(array $data): string
    {
        $html = $this->formatter->format($data, DisplayOptions::default(), OutputFormat::HTML);
        return "<div class='debug-output'>{$html}</div>";
    }
}

Custom Configuration Example

use App\Framework\Display\Formatters\AutoFormatter;
use App\Framework\Display\ValueObjects\DisplayOptions;
use App\Framework\Display\ValueObjects\DisplayRules;

// Create custom configuration
$rules = DisplayRules::default()
    ->withMaxArraySizeForSummary(500)
    ->withMaxItems(50);

$options = DisplayOptions::default()
    ->withMaxDepth(3)
    ->withFormatStyle('tree')
    ->withRules($rules);

$formatter = new AutoFormatter();
$output = $formatter->format($data, $options, OutputFormat::CONSOLE);

Formatting Different Data Types

$formatter = new AutoFormatter();

// Array
$array = ['key' => 'value', 'nested' => ['a' => 1, 'b' => 2]];
echo $formatter->formatForConsole($array);

// Object
$user = new User(name: 'John', age: 30);
echo $formatter->formatForConsole($user);

// JSON
$json = '{"name":"John","age":30}';
echo $formatter->formatForConsole($json);

// Class structure
echo $formatter->formatForConsole(User::class);

// Directory structure
echo $formatter->formatForConsole('/path/to/directory');

API Reference

Main Classes

  • AutoFormatter: Main entry point for automatic formatting
  • ArrayFormatter: Formats arrays
  • ObjectFormatter: Formats objects
  • ClassFormatter: Formats classes
  • FilesystemFormatter: Formats filesystem structures
  • JsonFormatter: Formats JSON strings
  • YamlFormatter: Formats YAML strings
  • XmlFormatter: Formats XML strings
  • CsvFormatter: Formats CSV strings

Value Objects

  • DisplayOptions: Configuration options for display
  • DisplayRules: Rules for filtering and performance
  • OutputFormat: Output format enum (CONSOLE, HTML)
  • ArrayStructure: Normalized array representation
  • ObjectStructure: Normalized object representation
  • ClassStructure: Normalized class representation
  • DirectoryStructure: Normalized directory representation

Interfaces

  • ValueObjectFormatterInterface: Interface for custom Value Object formatters

For detailed API documentation, see the PHPDoc comments in the source files.