Installation:
composer require exercise/htmlpurifier-bundle
Add the bundle to config/bundles.php:
return [
// ...
Exercise\HTMLPurifierBundle\ExerciseHTMLPurifierBundle::class => ['all' => true],
];
First Use Case: Inject the purifier service into a controller or service:
use Exercise\HTMLPurifierBundle\HTMLPurifier;
class MyController extends AbstractController
{
public function __construct(private HTMLPurifier $purifier) {}
public function sanitize(Request $request)
{
$dirtyHtml = $request->request->get('content');
$cleanHtml = $this->purifier->purify($dirtyHtml);
return new Response($cleanHtml);
}
}
Basic Configuration:
Override defaults in config/packages/exercise_html_purifier.yaml:
exercise_html_purifier:
default_cache_serializer_path: '%kernel.project_dir%/var/cache/htmlpurifier'
default_cache_serializer_permissions: 493
Sanitizing User Input:
// Controller/Service
$purified = $this->purifier->purify($userInput, 'custom_profile');
custom_profile) for different sanitization rules.Dynamic Profile Switching:
# config/packages/exercise_html_purifier.yaml
exercise_html_purifier:
profiles:
admin_panel:
HTML.Allowed: 'p[style],strong,em,a[href|title],ul,ol,li'
HTML.TargetBlank: true
public_content:
HTML.Allowed: 'p,br,strong,em,a[href],img[src|alt]'
$this->purifier->purify($html, 'admin_panel');
Integration with Forms:
DataTransformer to auto-sanitize form submissions:use Exercise\HTMLPurifierBundle\HTMLPurifier;
class HtmlSanitizerTransformer implements DataTransformerInterface
{
public function __construct(private HTMLPurifier $purifier) {}
public function transform($value): ?string
{
return $this->purifier->purify($value);
}
public function reverseTransform($value): string
{
return $value; // No reverse transform needed
}
}
Twig Integration:
{{ user_content|purify('public_content') }}
Add to twig.yaml:
twig:
filters:
purify: Exercise\HTMLPurifierBundle\Twig\PurifyFilter
Batch Processing:
$purifier = $this->purifier->getPurifier('default');
$batch = ['<script>alert(1)</script>', '<b>Safe</b>'];
array_walk($batch, fn(&$item) => $item = $purifier->purify($item));
Performance Overhead:
default_cache_serializer_path). Monitor cache growth in production.default_cache_serializer_permissions if filesystem permissions cause issues (e.g., 493 for 0755).Profile Inheritance:
default. Override explicitly:profiles:
strict:
HTML.Allowed: 'p,br' # Overrides default's allowed tags
HTML.TargetBlank: false # Disables target="_blank"
XSS Edge Cases:
$this->purifier->purify('<svg onload=alert(1)>', 'strict');
SecurityContext for additional checks.Configuration Validation:
HTML.Allowed) throws silent failures. Validate with:php bin/console debug:config exercise_html_purifier
Dependency Conflicts:
white-october/pagerfanta-bundle). HTMLPurifier is not a replacement for CSRF protection.Log Purified Output:
$this->purifier->purify($html, 'debug', [
'HTMLPurifier.Logging' => true,
'HTMLPurifier.Logger' => new \Exercise\HTMLPurifierBundle\Logger\MonologLogger($this->logger),
]);
Inspect Cache:
var/cache/htmlpurifier/ for corrupted cache files (delete and regenerate if needed).Profile Testing:
HTMLPurifier_ConfigSchema to validate profiles:$config = $this->purifier->getConfig('custom_profile');
$config->validate();
Custom Profiles via Code:
$this->purifier->addProfile('dynamic_profile', [
'HTML.Allowed' => 'div[class],span',
'Attr.AllowedFrame' => ['src'],
]);
Event Listeners:
exercise.htmlpurifier.purify events to log/transform input:// src/EventListener/PurifierListener.php
public function onPurify(PurifyEvent $event) {
$event->setHtml(str_replace('&', '&', $event->getHtml()));
}
Register in services.yaml:
services:
App\EventListener\PurifierListener:
tags:
- { name: 'kernel.event_listener', event: 'exercise.htmlpurifier.purify' }
Override Default Config:
use Exercise\HTMLPurifierBundle\DependencyInjection\Configuration;
class CustomConfiguration extends Configuration
{
public function getKey() { return 'custom_htmlpurifier'; }
// Add custom parameters
}
Update Resources/config/services.yaml to point to your config class.
Performance Tuning:
exercise_html_purifier:
profiles:
no_cache:
Cache.SerializerPath: null
How can I help you explore Laravel packages today?