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

Filter Bundle Laravel Package

alhames/filter-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require alhames/filter-bundle
    

    Ensure your project uses Symfony 6.x/7.x and PHP 8.0+.

  2. Bundle Registration: Add to config/bundles.php:

    return [
        // ...
        Alhames\FilterBundle\FilterBundle::class => ['all' => true],
    ];
    
  3. First Use Case: Define a filter in a YAML config (e.g., config/filters.yaml):

    filters:
        user:
            name: string
            email: email
            is_active: boolean
            rating: float
            ip_address: ip
    

    Then inject the filter service in a controller/service:

    use Alhames\FilterBundle\Filter\FilterManager;
    
    public function __construct(private FilterManager $filterManager) {}
    
    public function applyFilters(Request $request) {
        $filters = $this->filterManager->getFilters('user');
        // Process filters...
    }
    

Implementation Patterns

Core Workflow

  1. Filter Definition: Define filters in YAML/array format with field types (string, boolean, float, ip, etc.). Example:

    filters:
        product:
            price: float[min: 0, max: 1000, format: decimal]
            in_stock: boolean[required: true]
            ip: ip[default: 0]
    
  2. Validation & Sanitization: Use the FilterManager to validate/sanitize input:

    $validated = $filterManager->validate($inputData, 'product');
    
  3. Database Field Generation: Dynamically generate SQL field definitions:

    $dbField = $filterManager->getFilter('price')->getDbField();
    // Output: `FLOAT UNSIGNED NOT NULL DEFAULT '0.00'`
    
  4. Integration with Forms: Bind filters to Symfony forms for type-safe handling:

    $form = $this->createFormBuilder()
        ->add('price', FloatType::class, [
            'filter_config' => ['min' => 0, 'max' => 1000]
        ])
        ->getForm();
    

Advanced Patterns

  • Custom Filter Types: Extend AbstractFilter to add new types (e.g., DateFilter):

    class DateFilter extends AbstractFilter {
        public function getDbField(array $config = []): string {
            return 'DATE' . ($config['required'] ? ' NOT NULL' : '');
        }
    }
    

    Register in services.yaml:

    services:
        App\Filter\DateFilter:
            tags: { name: alhames.filter.filter, type: date }
    
  • Dynamic Filter Loading: Load filters from multiple sources (e.g., database) via FilterLoaderInterface:

    $loader = new YamlFileLoader($this->container->getParameter('kernel.project_dir').'/config');
    $filterManager->setLoader($loader);
    
  • Translation Support: Localize filter labels/errors:

    # config/filters.yaml
    filters:
        user:
            name: { label: 'user.name', type: string }
    
    $translator = $this->container->get('translator');
    $label = $translator->trans('user.name');
    

Gotchas and Tips

Common Pitfalls

  1. Type Mismatches:

    • float fields with format: integer will generate raw INT without precision.
    • Fix: Explicitly set format: decimal for floats requiring precision.
  2. IP Address Handling:

    • The ip filter stores IPs as unsigned integers (e.g., 192.168.1.13232235777).
    • Tip: Use FilterManager::convertIpToInt()/convertIntToIp() for conversion.
  3. Default Values:

    • Boolean defaults must be 0/1 (not false/true) in SQL.
    • Workaround: Use default: 0 for false in config.
  4. YAML Parsing:

    • Nested arrays in YAML (e.g., config: [key: value]) may break.
    • Fix: Use inline syntax:
      filters:
          product:
              tags: { type: string, config: { min_length: 3, max_length: 255 } }
      

Debugging Tips

  • Validate Config: Use FilterManager::validateConfig() to check for invalid types/configs:

    try {
        $filterManager->validateConfig($config);
    } catch (InvalidFilterConfigException $e) {
        // Handle error
    }
    
  • SQL Field Debugging: Log generated fields for inspection:

    $filters = $filterManager->getFilters('user');
    foreach ($filters as $name => $filter) {
        $this->logger->debug("Field [$name]: {$filter->getDbField()}");
    }
    

Extension Points

  1. Custom Validators: Override validate() in a custom filter to add logic:

    public function validate($value, array $config = []): mixed {
        if ($value < 0 && !$config['allow_negative']) {
            throw new \InvalidArgumentException('Negative values not allowed.');
        }
        return parent::validate($value, $config);
    }
    
  2. Database-Specific Adjustments: Extend getDbField() for platform-specific SQL (e.g., PostgreSQL):

    public function getDbField(array $config = []): string {
        $field = parent::getDbField($config);
        return str_replace('FLOAT', 'REAL', $field); // PostgreSQL uses REAL
    }
    
  3. Performance:

    • Cache FilterManager instances if filters are static.
    • Tip: Use FilterManager::getFilters() with a cache key:
      $filters = $filterManager->getFilters('user', 'cache_key');
      
  4. Testing:

    • Mock FilterManager in tests:
      $filterManager = $this->createMock(FilterManager::class);
      $filterManager->method('validate')->willReturn($expectedData);
      
    • Test getDbField() with edge cases (e.g., max values exceeding DB_MAX_SIGNED_FLOAT).
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui