Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Decorator Laravel Package

cleentfaar/decorator

Laravel/PHP decorator helper to wrap classes and add behavior without modifying the original. Provides a lightweight Decorator pattern implementation for cleaner, composable enhancements and feature extensions in your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require cleentfaar/decorator
    

    Register the service provider in config/app.php:

    'providers' => [
        // ...
        Cleentfaar\Decorator\DecoratorServiceProvider::class,
    ],
    
  2. Basic Usage Decorate a value (e.g., a string, number, or object) for template rendering:

    use Cleentfaar\Decorator\Decorator;
    
    $decorator = app(Decorator::class);
    $decorated = $decorator->decorate('2023-10-01', 'date', ['format' => 'Y-m-d']);
    // Outputs: <span class="date">October 1, 2023</span>
    
  3. First Use Case Format dates, numbers, or booleans in Blade templates without manual logic:

    // In a controller
    $user = User::find(1);
    $decoratedUser = $decorator->decorate($user, 'user', [
        'date_format' => 'F j, Y',
        'boolean_format' => ['Yes', 'No']
    ]);
    
    // In Blade
    @foreach ($decoratedUser->posts as $post)
        <li>{{ $post->created_at }}</li> <!-- Renders as formatted date -->
    @endforeach
    

Implementation Patterns

Common Workflows

  1. Decorating Collections Apply decorators to Eloquent collections for consistent rendering:

    $decoratedPosts = Post::all()->map(function ($post) {
        return $decorator->decorate($post, 'post', [
            'title_length' => 50,
            'date_format' => 'M d, Y'
        ]);
    });
    
  2. Dynamic Decorators in Blade Use decorators conditionally based on context:

    @php
        $decorator = app(Decorator::class);
        $value = $user->is_active ? 'Active' : 'Inactive';
        $decorated = $decorator->decorate($value, 'boolean');
    @endphp
    <span>{{ $decorated }}</span>
    
  3. Custom Decorator Types Extend the package for domain-specific formatting:

    // Register a new decorator type (e.g., 'currency')
    $decorator->addDecorator('currency', function ($value, $options) {
        return '<span class="currency">' . number_format($value, 2, ',', '.') . ' ' . $options['currency'] ?? '$' . '</span>';
    });
    
    // Usage
    $decorated = $decorator->decorate(1234.56, 'currency', ['currency' => '€']);
    
  4. Integration with Form Requests Decorate validation errors or inputs for user-friendly display:

    public function withValidator($validator, $request, $errors)
    {
        $errors->setDecorated(function ($message) {
            return app(Decorator::class)->decorate($message, 'error');
        });
    }
    
  5. Caching Decorated Values Cache frequently used decorated values to avoid reprocessing:

    $cacheKey = 'decorated_user_' . $user->id;
    $decorated = Cache::remember($cacheKey, now()->addHours(1), function () use ($user) {
        return $decorator->decorate($user, 'user', ['date_format' => 'Y-m-d']);
    });
    

Gotchas and Tips

Pitfalls

  1. Deprecated Package

    • Last updated in 2014; ensure compatibility with PHP 8.x/Laravel 9+ (may require patches or forks).
    • Test thoroughly for edge cases (e.g., null values, nested objects).
  2. No Built-in Type Safety

    • Decorators assume input types (e.g., 'date' for strings, 'boolean' for booleans). Pass wrong types, and you’ll get unexpected output.
    • Fix: Validate inputs before decorating or add type checks:
      if (!is_string($value)) {
          throw new \InvalidArgumentException('Date decorator requires a string.');
      }
      
  3. Limited Default Decorators

    • Only basic types (date, boolean, number) are included. Custom decorators are required for most use cases.
    • Tip: Create a base decorator class for reusable logic:
      class AppDecorator extends \Cleentfaar\Decorator\Decorator {
          public function __construct() {
              parent::__construct();
              $this->addDecorator('app_date', function ($value) {
                  return '<time datetime="' . $value . '">' . \Carbon\Carbon::parse($value)->format('M j, Y') . '</time>';
              });
          }
      }
      
  4. HTML Escaping

    • Decorators output raw HTML. Escape dynamically generated content to prevent XSS:
      {!! e($decorator->decorate($value, 'html')) !!}
      
  5. Performance Overhead

    • Decorating large collections or complex objects can slow down rendering.
    • Tip: Decorate only what’s necessary or use lazy loading (e.g., decorate in Blade, not in the controller).

Debugging

  1. Inspect Decorator Output Temporarily log decorated values to debug formatting:

    \Log::debug('Decorated:', ['value' => $decorated]);
    
  2. Check Registered Decorators List available decorators to verify custom ones are loaded:

    $decorator->getDecorators(); // Returns array of registered decorators
    
  3. Handle Missing Decorators Gracefully fall back for unregistered types:

    try {
        $decorated = $decorator->decorate($value, 'unknown_type');
    } catch (\InvalidArgumentException $e) {
        $decorated = $value; // Fallback to raw value
    }
    

Extension Points

  1. Override Default Decorators Replace built-in decorators (e.g., 'date') in the service provider’s boot method:

    public function boot()
    {
        $this->app->make(Decorator::class)->addDecorator('date', function ($value) {
            return '<span class="custom-date">' . \Carbon\Carbon::parse($value)->format('l, F jS') . '</span>';
        });
    }
    
  2. Add Decorator Options Extend decorator options dynamically:

    $decorator->addDecorator('user', function ($user, $options) {
        $options = array_merge([
            'avatar_size' => 50,
            'name_length' => 20
        ], $options);
    
        return sprintf(
            '<div class="user-card"><img src="%s" width="%d">%s</div>',
            $user->avatar_url,
            $options['avatar_size'],
            Str::limit($user->name, $options['name_length'])
        );
    });
    
  3. Integrate with Laravel’s Blade Directives Create a Blade directive for concise syntax:

    Blade::directive('decorate', function ($expression) {
        return "<?php echo app(\Cleentfaar\Decorator\Decorator::class)->decorate({$expression[0]}, {$expression[1]}); ?>";
    });
    
    // Usage in Blade
    @decorate($user->created_at, 'date', ['format' => 'Y-m-d'])
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity