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

Purifier Laravel Package

mews/purifier

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require mews/purifier
    
    • Auto-discovered in Laravel 5.5+; manually register provider/alias for older versions.
  2. First Use Case: Sanitize user input (e.g., form submissions, comments):

    use Mews\Purifier\Facades\Purifier;
    
    $cleanHtml = Purifier::clean($userInput);
    
    • Default config allows basic HTML (div, a, p, etc.) and CSS (e.g., font, color).
  3. Where to Look First:

    • Config: Publish defaults with php artisan vendor:publish --provider="Mews\Purifier\PurifierServiceProvider".
    • Facade: Purifier::clean($html, $configKey) for dynamic sanitization.
    • Casts: Use CleanHtml, CleanHtmlInput, or CleanHtmlOutput in Eloquent models (Laravel 7+).

Implementation Patterns

Core Workflows

  1. Request Sanitization:

    • Middleware for global input cleaning:
      public function handle($request, Closure $next) {
          $request->merge([
              'content' => Purifier::clean($request->content, 'default')
          ]);
          return $next($request);
      }
      
  2. Dynamic Configs:

    • Reuse predefined configs (e.g., titles, youtube) or pass custom arrays:
      // Allow IDs in headings
      Purifier::clean($html, ['Attr.EnableID' => true]);
      
      // Custom URI filtering (e.g., allow only YouTube/Vimeo iframes)
      Purifier::clean($html, 'youtube');
      
  3. Eloquent Integration:

    • Auto-cleaning: Use casts to sanitize on save()/get():
      protected $casts = [
          'description' => CleanHtmlInput::class, // Sanitize on input
          'formatted_content' => CleanHtmlOutput::class, // Sanitize on output
      ];
      
  4. URI Filtering:

    • Extend HTMLPurifier’s URI validation (e.g., whitelist domains):
      Purifier::clean($html, 'default', function ($config) {
          $config->getDefinition('URI')->addHost($config, 'trusted-domain.com');
      });
      

Integration Tips

  • Blade Directives: Create a custom directive for templated sanitization:

    Blade::directive('clean', function ($html) {
        return "<?php echo Purifier::clean($html, 'default'); ?>";
    });
    

    Usage:

    {!! clean($userHtml) !!}
    
  • API Responses: Sanitize before JSON serialization:

    return response()->json([
        'content' => Purifier::clean($request->content)
    ]);
    
  • Testing: Mock the facade for unit tests:

    $this->app->instance('Purifier', Mockery::mock('Mews\Purifier\Facades\Purifier'));
    

Gotchas and Tips

Pitfalls

  1. Performance:

    • Caching: Enable cachePath in config to avoid recompiling definitions on every request.
    • Overhead: Heavy custom definitions (e.g., HTML5) increase memory usage. Test with memory_get_usage().
  2. Config Overrides:

    • Priority: Inline configs override published configs. Use array_merge to extend defaults:
      $config = array_merge(config('purifier.settings.default'), ['Attr.EnableID' => true]);
      Purifier::clean($html, $config);
      
  3. XSS Edge Cases:

    • JavaScript: Even with HTML.Allowed, malicious scripts can slip through via onerror or style attributes. Use HTML.SafeObject or HTML.Safe sparingly.
    • Data URIs: Block with:
      $config->getDefinition('URI')->addFilter(new HTMLPurifier_URIFilter_DataURI());
      
  4. Eloquent Casts:

    • Double Cleaning: CleanHtml runs on both get/set. Use CleanHtmlInput/Output separately to avoid redundant passes.

Debugging

  • Validation Errors: HTMLPurifier throws HTMLPurifier_Exception for malformed input. Catch and log:

    try {
        Purifier::clean($html);
    } catch (HTMLPurifier_Exception $e) {
        Log::error('Purifier error: ' . $e->getMessage());
        return back()->withInput();
    }
    
  • Config Validation: Use HTMLPurifier_Config::validate() to check configs before runtime:

    $config = HTMLPurifier_Config::create($settings);
    $config->validate();
    

Extension Points

  1. Custom Definitions:

    • Extend HTMLPurifier’s core definitions (e.g., add details/summary for HTML5):
      $config->define('custom_definition', [
          'elements' => [
              ['details', 'Block', 'Flow', 'Common'],
              ['summary', 'Inline', 'Flow', 'Common'],
          ],
      ]);
      
  2. Filter Chains:

    • Chain multiple filters (e.g., strip comments + sanitize):
      $html = strip_comments($html);
      $html = Purifier::clean($html);
      
  3. Event Hooks:

    • Listen for purifier.clean events to log sanitized content:
      Purifier::clean($html)->then(function ($cleaned) {
          Log::debug('Sanitized HTML:', ['content' => $cleaned]);
      });
      

Pro Tips

  • Profile Configs: Use HTMLPurifier_Config::getHTMLDefinition() to inspect active rules:

    $definition = Purifier::getConfig('default')->getHTMLDefinition();
    dd($definition->getElement('a')->getAttributes());
    
  • Fallbacks: Provide fallback HTML for invalid input:

    $cleaned = Purifier::clean($html, 'default');
    $cleaned = $cleaned ?: '<p>No valid content provided.</p>';
    
  • Laravel 11+: Leverage app('purifier') for container binding:

    $this->app->bind('purifier', function () {
        return Purifier::getConfig('strict');
    });
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle