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

Directoryscanner Laravel Package

theseer/directoryscanner

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require theseer/directoryscanner
    

    No additional configuration is needed—autoload via Composer.

  2. First Use Case: Scan a directory recursively and filter files by extension:

    use Theseer\DirectoryScanner\DirectoryScanner;
    
    $scanner = new DirectoryScanner();
    $files = $scanner->scan(['/path/to/directory', '*.php']);
    foreach ($files as $file) {
        echo $file->getPathname() . "\n";
    }
    
  3. Key Classes:

    • DirectoryScanner: Core class for scanning.
    • File: Represents scanned files (extends SplFileInfo).
    • Directory: Represents scanned directories (extends SplFileInfo).
  4. Where to Look First:


Implementation Patterns

Core Workflows

  1. Basic Scanning:

    $scanner = new DirectoryScanner();
    $results = $scanner->scan(['/path/to/directory', '*.{php,js}']);
    
    • Supports glob patterns (e.g., *.php, **/*.md for recursive subdirectories).
    • Returns File/Directory objects (not raw strings).
  2. Filtering:

    • Post-scan filtering (Laravel-style):
      $files = $scanner->scan(['/path/to/directory', '*']);
      $filtered = array_filter($files, fn($file) => $file->getExtension() === 'php');
      
    • Pre-scan filtering: Use glob patterns in the scan arguments.
  3. Integration with Laravel:

    • Service Provider Binding:
      $this->app->singleton(DirectoryScanner::class, fn() => new DirectoryScanner());
      
    • Artisan Command:
      use Theseer\DirectoryScanner\DirectoryScanner;
      
      class ScanCommand extends Command {
          protected $signature = 'scan:files {directory}';
          public function handle(DirectoryScanner $scanner) {
              $files = $scanner->scan([$this->argument('directory'), '*.php']);
              $this->info(count($files) . ' files found.');
          }
      }
      
  4. Performance Optimization:

    • For large directories, use specific globs (e.g., **/*.php) to avoid scanning all files.
    • Cache results if scanning the same directory repeatedly:
      $cacheKey = 'scanned_files_' . md5($directory);
      $files = cache()->remember($cacheKey, now()->addHours(1), fn() =>
          $scanner->scan([$directory, '*.php'])
      );
      
  5. Async Processing:

    • Wrap scans in Laravel Queues for background processing:
      class ScanJob implements ShouldQueue {
          public function handle(DirectoryScanner $scanner) {
              $files = $scanner->scan([storage_path('app'), '*.jpg']);
              // Process files asynchronously
          }
      }
      
  6. Laravel Filesystem Integration:

    • Use with Laravel’s Storage facade for cloud storage:
      $path = Storage::path('public/uploads');
      $files = $scanner->scan([$path, '*.png']);
      

Gotchas and Tips

Pitfalls

  1. Case Sensitivity:

    • Glob patterns are case-sensitive on Linux/macOS but not on Windows.
    • Workaround: Normalize filenames if cross-platform compatibility is needed:
      $filtered = array_filter($files, fn($file) =>
          strtolower($file->getExtension()) === 'php'
      );
      
  2. Symbolic Links:

    • By default, DirectoryScanner follows symlinks, which can lead to infinite loops or unexpected results.
    • Disable symlink following with:
      $scanner = new DirectoryScanner();
      $scanner->ignoreSymlinks(true);
      
  3. Permission Issues:

    • Scanning directories with restricted permissions may throw exceptions.
    • Handle gracefully:
      try {
          $files = $scanner->scan([$directory, '*']);
      } catch (\RuntimeException $e) {
          Log::error('Scan failed: ' . $e->getMessage());
      }
      
  4. Memory Limits:

    • Large scans may hit PHP’s memory_limit.
    • Use chunking or generators for large directories:
      $iterator = $scanner->scan([$directory, '*']);
      foreach ($iterator as $file) {
          // Process one file at a time
      }
      
  5. Path Handling:

    • Ensure paths are absolute or relative to the working directory.
    • Use realpath() for consistency:
      $absolutePath = realpath($directory);
      $files = $scanner->scan([$absolutePath, '*']);
      

Debugging Tips

  1. Enable Verbose Output:

    • Temporarily enable debug mode to log scanned paths:
      $scanner->setVerbose(true);
      
  2. Check Glob Patterns:

    • Test glob patterns in isolation (e.g., glob('/path/to/directory/*.php')) to validate they match expected files.
  3. Validate File Objects:

    • Ensure File objects are properly instantiated:
      foreach ($files as $file) {
          if (!$file instanceof \Theseer\DirectoryScanner\File) {
              throw new \RuntimeException('Invalid file object');
          }
      }
      

Extension Points

  1. Custom Filters:

    • Extend the scanner to add custom filters:
      $scanner->addFilter(function($file) {
          return $file->getSize() > 1024; // Filter files > 1KB
      });
      
  2. Event Dispatching:

    • Wrap the scanner to dispatch events (e.g., FileScanned):
      $scanner = new DirectoryScanner();
      $scanner->on('scan.complete', function($files) {
          event(new FilesScanned($files));
      });
      
  3. Laravel Service Provider:

    • Bind the scanner with additional configurations:
      $this->app->singleton(DirectoryScanner::class, function() {
          $scanner = new DirectoryScanner();
          $scanner->ignoreSymlinks(true);
          return $scanner;
      });
      

Laravel-Specific Tips

  1. Use with Storage Facade:

    • Combine with Laravel’s Storage for cloud storage support:
      $path = Storage::disk('s3')->path('uploads');
      $files = $scanner->scan([$path, '*.jpg']);
      
  2. Queue Background Scans:

    • Offload heavy scans to queues:
      ScanJob::dispatch($directory, '*.php')->onQueue('scans');
      
  3. Integration with Eloquent:

    • Attach scanned files to models:
      $files = $scanner->scan([storage_path('app'), '*.pdf']);
      foreach ($files as $file) {
          $model->attachFile($file->getPathname());
      }
      
  4. Testing:

    • Mock the scanner in unit tests:
      $mockScanner = Mockery::mock(DirectoryScanner::class);
      $mockScanner->shouldReceive('scan')
          ->once()
          ->andReturn([new \Theseer\DirectoryScanner\File('/fake/path/file.txt')]);
      
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.
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
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope