Weave 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

Sniffer Laravel Package

alexandre-mace/sniffer

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require alexandre-mace/sniffer
    

    Ensure your project uses PHP 7.1+ and Symfony 4.4.x components (HTTP Foundation, Kernel, Validator, Serializer).

  2. First Use Case: Extracting and Validating a Request DTO

    use AlexandreMace\Sniffer\Sniffer;
    
    // Initialize Sniffer with a request object
    $sniffer = new Sniffer($request);
    
    // Extract a DTO class from a request (e.g., JSON payload)
    $dto = $sniffer->extract('App\DTO\MyRequestDTO');
    
    // Validate the extracted DTO
    $errors = $sniffer->validate($dto);
    if ($errors->count() > 0) {
        // Handle validation errors
    }
    
  3. Key Files to Review

    • src/Sniffer.php: Core class for extraction and validation.
    • tests/: Unit tests for expected behavior (e.g., SnifferTest.php).
    • composer.json: Dependencies and constraints.

Implementation Patterns

Workflow: API Request Handling

  1. Middleware Integration Use the Sniffer in middleware to validate incoming requests early:

    use AlexandreMace\Sniffer\Sniffer;
    use Symfony\Component\HttpFoundation\Request;
    
    public function handle(Request $request, Closure $next)
    {
        $sniffer = new Sniffer($request);
        $dto = $sniffer->extract('App\DTO\UserCreateDTO');
    
        if ($sniffer->validate($dto)->count() > 0) {
            return response()->json(['errors' => $sniffer->getErrors()], 400);
        }
    
        return $next($request);
    }
    
  2. DTO Design Patterns

    • Naming Conventions: Prefix DTO classes with DTO (e.g., UserCreateDTO).
    • Validation Annotations: Use Symfony Validator constraints (e.g., @Assert\NotBlank()).
    • Serialization: Ensure DTOs implement Serializable or use #[SerializedName] for custom field mapping.
  3. Integration with Symfony Components

    • Serializer: Customize serialization/deserialization in config/packages/serializer.yaml:
      framework:
          serializer:
              mapping:
                  paths: ['%kernel.project_dir%/config/serializer']
      
    • Validator: Extend validation with custom constraints in config/validator/validation.yaml.
  4. Command-Line Usage For testing or bulk validation:

    $sniffer = new Sniffer($request);
    $dto = $sniffer->extract('App\DTO\ReportDTO');
    $errors = $sniffer->validate($dto);
    
    // Log or export errors (e.g., to a file)
    file_put_contents('validation_errors.log', print_r($errors, true));
    

Gotchas and Tips

Pitfalls

  1. Dependency Conflicts

    • The package locks Symfony components to 4.4.*. If your project uses a different version (e.g., Symfony 5/6), conflicts may arise.
    • Fix: Use composer why-not to diagnose conflicts or override dependencies in composer.json:
      "extra": {
          "symfony-require": "4.4.*"
      }
      
  2. DTO Class Not Found

    • If extract() fails with ClassNotFoundException, ensure:
      • The DTO class exists and is autoloaded (check composer dump-autoload).
      • The namespace is correct (e.g., App\DTO\MyDTO, not DTO\MyDTO).
  3. Validation Errors Not Triggering

    • If $sniffer->validate() returns no errors, verify:
      • The DTO has validation annotations (e.g., @Assert\Type("string")).
      • The request payload matches the DTO structure (e.g., JSON keys match DTO properties).
  4. Performance Overhead

    • Extracting and validating DTOs on every request adds latency.
    • Optimization: Cache DTO metadata or use the Sniffer selectively (e.g., only for critical endpoints).

Debugging Tips

  1. Enable Debug Mode Temporarily enable Symfony’s debug mode to inspect validation errors:

    $sniffer->setDebug(true);
    
  2. Log Raw Data Dump the extracted DTO or request data for debugging:

    \Symfony\Component\VarDumper\VarDumper::dump($dto);
    
  3. Custom Error Handling Override error formatting:

    $errors = $sniffer->validate($dto);
    foreach ($errors as $error) {
        logger()->error("Validation failed: {$error->getMessage()}");
    }
    

Extension Points

  1. Custom Validators Extend the Sniffer to support custom validation logic:

    class CustomSniffer extends Sniffer
    {
        public function validate($dto, array $customRules = [])
        {
            // Add custom rules before/after Symfony validation
            $errors = parent::validate($dto);
            foreach ($customRules as $rule) {
                if (!$rule($dto)) {
                    $errors->addViolation(new \Symfony\Component\Validator\ConstraintViolation(
                        'Custom rule failed',
                        null,
                        [],
                        $dto,
                        'custom_rule',
                        null
                    ));
                }
            }
            return $errors;
        }
    }
    
  2. Event Dispatching Trigger events before/after extraction or validation:

    use Symfony\Component\EventDispatcher\EventDispatcher;
    
    $dispatcher = new EventDispatcher();
    $sniffer = new Sniffer($request, $dispatcher);
    
    // Listen for events
    $dispatcher->addListener('sniffer.extract', function ($event) {
        logger()->info('DTO extracted', ['dto' => $event->getDto()]);
    });
    
  3. Configuration Overrides Override default behavior via constructor options:

    $sniffer = new Sniffer($request, [
        'serializer_groups' => ['default', 'custom_group'],
        'validation_groups' => ['registration', 'default'],
    ]);
    

Configuration Quirks

  • Serializer Groups: Ensure DTO properties are mapped to the correct serializer groups in config/serializer/mapping.yaml:
    App\DTO\UserDTO:
        properties:
            email:
                groups: [registration, default]
    
  • Circular References: If DTOs reference each other circularly, configure the serializer to handle this:
    $sniffer->getSerializer()->enableMaxDepthChecks(false);
    
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table