Skip to content

Latest commit

 

History

History
240 lines (185 loc) · 7.25 KB

File metadata and controls

240 lines (185 loc) · 7.25 KB

KaririCode Framework: ProcessorPipeline

PHP 8.4+ MIT License ARFA 1.3

A robust, immutable processor pipeline component for the KaririCode Framework. Enables modular, configurable processing chains for data transformation, validation, and sanitization — fully compliant with ARFA 1.3.

Features

  • Immutable pipelineswithProcessor() returns new instances (ARFA P1)
  • Context-based registry — collision-free processor management across domains
  • Flexible specification format — simple lists, enable/disable flags, and configuration arrays
  • Configurable processors — runtime configuration via ConfigurableProcessor interface
  • Error collectionProcessingResultCollection for non-halting error aggregation
  • PHP 8.4+readonly class, asymmetric visibility, constructor promotion
  • Zero external dependencies — depends only on kariricode/contract
  • Structured exceptions — all exceptions carry context arrays for observability

Installation

composer require kariricode/processor-pipeline

Requirements: PHP 8.4+, Composer

Quick Start

use KaririCode\Contract\Processor\Processor;
use KaririCode\ProcessorPipeline\ProcessorRegistry;
use KaririCode\ProcessorPipeline\ProcessorBuilder;

// 1. Define processors
class TrimProcessor implements Processor
{
    public function process(mixed $input): mixed
    {
        return trim((string) $input);
    }
}

class LowercaseProcessor implements Processor
{
    public function process(mixed $input): mixed
    {
        return strtolower((string) $input);
    }
}

// 2. Register
$registry = new ProcessorRegistry();
$registry
    ->register('sanitizer', 'trim', new TrimProcessor())
    ->register('sanitizer', 'lowercase', new LowercaseProcessor());

// 3. Build & Execute
$builder = new ProcessorBuilder($registry);
$pipeline = $builder->buildPipeline('sanitizer', ['trim', 'lowercase']);

$result = $pipeline->process('  HELLO WORLD  ');
// Result: 'hello world'

Usage

Configurable Processors

use KaririCode\Contract\Processor\ConfigurableProcessor;

class LengthValidator implements ConfigurableProcessor
{
    private int $minLength = 0;
    private int $maxLength = PHP_INT_MAX;

    public function configure(array $options): void
    {
        $this->minLength = $options['minLength'] ?? $this->minLength;
        $this->maxLength = $options['maxLength'] ?? $this->maxLength;
    }

    public function process(mixed $input): mixed
    {
        $length = mb_strlen((string) $input);

        if ($length < $this->minLength || $length > $this->maxLength) {
            throw new \InvalidArgumentException(
                "Length must be between {$this->minLength} and {$this->maxLength}."
            );
        }

        return $input;
    }
}

$registry->register('validator', 'length', new LengthValidator());

$pipeline = $builder->buildPipeline('validator', [
    'length' => ['minLength' => 3, 'maxLength' => 50],
]);

Processor Specification Format

$pipeline = $builder->buildPipeline('validator', [
    'required',                  // Simple: enabled
    'trim' => true,              // Explicit: enabled
    'optional' => false,         // Explicit: disabled (skipped)
    'length' => ['min' => 3],    // Configured
]);

Immutable Pipeline Composition

$basePipeline = $builder->buildPipeline('sanitizer', ['trim']);
$extendedPipeline = $basePipeline->withProcessor(new LowercaseProcessor());

// $basePipeline still has 1 processor
// $extendedPipeline has 2 processors

Error Collection

use KaririCode\ProcessorPipeline\Handler\ProcessorHandler;
use KaririCode\ProcessorPipeline\Result\ProcessingResultCollection;

$results = new ProcessingResultCollection();

// Wrap processors with error collection
$handler = new ProcessorHandler(
    processor: new EmailValidator(),
    resultCollection: $results,
    haltOnError: false,
);

$output = $handler->process('invalid-email');

if ($results->hasErrors()) {
    foreach ($results->getErrors() as $processor => $errors) {
        foreach ($errors as $error) {
            echo "{$processor}: {$error['message']}\n";
        }
    }
}

PHP 8.4 Attributes

use KaririCode\ProcessorPipeline\Attribute\Process;

class UserProfile
{
    #[Process(
        processors: ['required', 'length' => ['minLength' => 3]],
        messages: ['required' => 'Username is required.'],
    )]
    public private(set) string $username = '';

    #[Process(
        processors: ['trim', 'lowercase', 'email'],
        messages: ['email' => 'Invalid email.'],
    )]
    public private(set) string $email = '';
}

Architecture

Consumer Code
      │
      ▼
ProcessorBuilder ──→ ProcessorRegistry
      │                  (context → name → Processor)
      │ creates
      ▼
   Pipeline (immutable, readonly)
   [P₁, P₂, ..., Pₙ]
      │
      ▼
   process(input) → output

ARFA 1.3 Compliance

Principle Implementation
P1: Immutable State Pipeline is readonly class; withProcessor() returns new instance
P2: Reactive Flow Sequential composition: f₁ ∘ f₂ ∘ ... ∘ fₙ
P3: Adaptive Context Context-based registry; ConfigurableProcessor
P4: Protocol Agnostic No protocol coupling; works with HTTP, gRPC, CLI, etc.
P5: Observability Structured exceptions; ProcessingResultCollection tracing

Integration with KaririCode Components

Component Role
kariricode/contract Processor, ConfigurableProcessor interfaces
kariricode/validator Validation pipelines via #[Validate]
kariricode/sanitizer Sanitization pipelines via #[Sanitize]
kariricode/transformer Transformation pipelines via #[Transform]
kariricode/property-inspector Discovers #[Process] attributes on properties

Development

git clone https://github.com/KaririCode-Framework/kariricode-processor-pipeline.git
cd kariricode-processor-pipeline
composer install
kcode init
kcode test      # Run tests
kcode quality   # Full quality check

Documentation

License

MIT License — see LICENSE for details.

Support


Built with ❤️ by the KaririCode team. Empowering developers to create robust PHP applications.