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

Glob Finder Laravel Package

dantleech/glob-finder

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Dependencies

    composer require dantleech/glob-finder doctrine/phpcr doctrine/phpcr-odm
    

    Ensure your Laravel app uses doctrine/phpcr-bundle (Symfony) or manually configures PHPCR-ODM.

  2. First Use Case: Fetching Nodes

    use Dantleech\GlobFinder\PhpcrOdmTraversalFinder;
    
    // In a Laravel service or controller
    $dm = app('doctrine_phpcr.odm.document_manager');
    $finder = new PhpcrOdmTraversalFinder($dm);
    
    // Find all articles under /cmf/articles/
    $articles = $finder->find('/cmf/articles/*');
    
  3. Where to Look First

    • Core Class: PhpcrOdmTraversalFinder (handles glob-to-PHPCR conversion).
    • Tests: tests/ directory for edge cases (e.g., recursive globs, special chars).
    • PHPCR-ODM Docs: Doctrine PHPCR-ODM for node structure.

Implementation Patterns

Usage Patterns

  1. Glob Syntax

    • Basic: /path/to/* (matches direct children).
    • Recursive: /path/**/* (matches all descendants; not natively supported—see Gotchas).
    • Wildcards: *article* (matches "article", "blog_article", etc.).
  2. Laravel Integration

    • Service Provider:
      // app/Providers/AppServiceProvider.php
      public function register() {
          $this->app->singleton(PhpcrOdmTraversalFinder::class, function ($app) {
              return new PhpcrOdmTraversalFinder($app['doctrine_phpcr.odm.document_manager']);
          });
      }
      
    • Facade (Optional): Create a facade to simplify usage:
      // app/Facades/GlobFinder.php
      public static function find($pattern) {
          return app(PhpcrOdmTraversalFinder::class)->find($pattern);
      }
      
  3. Workflow: Content Migration

    // Extract all legacy nodes for migration
    $legacyNodes = app(PhpcrOdmTraversalFinder::class)->find('/legacy/*');
    foreach ($legacyNodes as $node) {
        $migrated = $this->migrateNode($node);
        $this->archiveOriginal($node);
    }
    
  4. Combining with PHPCR-ODM Queries Use globs to narrow results before applying filters:

    $candidateNodes = $finder->find('/products/*');
    $publishedProducts = $dm->createQueryBuilder('Product')
        ->where('node IN (:nodes)')
        ->setParameter('nodes', $candidateNodes)
        ->getQuery()
        ->getResult();
    

Integration Tips

  • Path Normalization: Ensure glob patterns match PHPCR’s case sensitivity (e.g., /Content/ vs. /content/).
  • Caching: Cache frequent glob results:
    $results = Cache::remember("glob_{$pattern}", now()->addHours(1), function () use ($finder, $pattern) {
        return $finder->find($pattern);
    });
    
  • Error Handling: Wrap calls in try-catch for invalid paths:
    try {
        $nodes = $finder->find('/invalid/path/*');
    } catch (\InvalidArgumentException $e) {
        Log::error("Glob pattern failed: {$e->getMessage()}");
    }
    

Gotchas and Tips

Pitfalls

  1. No Recursive Glob Support

    • The package does not support ** for recursive matching (e.g., /path/**/*).
    • Workaround: Use PHPCR’s native traversal:
      $session = $dm->getSession();
      $root = $session->getNode('/path');
      $nodes = $root->getNodes(); // Manual recursion needed
      
  2. PHPCR-Specific Path Handling

    • Glob patterns must match PHPCR’s node paths exactly (e.g., / vs. //).
    • Tip: Use $session->getRootNode()->getPath() to verify paths.
  3. Performance on Large Hierarchies

    • Glob queries can be slow for deep trees (e.g., /content/**/*).
    • Mitigation: Limit depth or use PHPCR’s getNodes() with constraints.
  4. Case Sensitivity

    • PHPCR’s case sensitivity depends on the backend (e.g., Jackrabbit is case-sensitive).
    • Tip: Normalize patterns (e.g., strtolower($pattern)) if needed.
  5. Dependency Conflicts

    • The package expects Doctrine PHPCR ODM ~1.2. Newer versions may break.
    • Fix: Fork and update dependencies or use a wrapper.

Debugging

  • Invalid Patterns: Check for:
    • Trailing slashes (/path/ vs. /path).
    • Special characters (e.g., ?, [).
  • PHPCR Errors: Enable PHPCR logging:
    $dm->getConfiguration()->setPHPCRConfiguration([
        'logging' => true,
    ]);
    
  • Node Not Found: Verify the path exists:
    $session = $dm->getSession();
    if (!$session->nodeExists('/path')) {
        throw new \RuntimeException("Path does not exist");
    }
    

Extension Points

  1. Custom Finder for Non-PHPCR Extend PhpcrOdmTraversalFinder to support other backends (e.g., filesystem):

    class FilesystemGlobFinder implements GlobFinderInterface {
        public function find($pattern) {
            return glob($pattern, GLOB_ONLYDIR | GLOB_BRACE);
        }
    }
    
  2. Add Recursive Support Override the finder to handle **:

    public function find($pattern) {
        if (strpos($pattern, '**') !== false) {
            return $this->recursiveFind($pattern);
        }
        return parent::find($pattern);
    }
    
  3. Laravel Events Dispatch events for glob results:

    event(new GlobFound($pattern, $results));
    

Config Quirks

  • PHPCR Session: The finder uses the default session from the DocumentManager. Ensure it’s configured:
    # config/packages/doctrine_phpcr.yaml
    doctrine_phpcr:
        session:
            backend: doctrine_phpcr.session.pdo
            connection: default
    
  • Node Types: Glob results include all node types. Filter by type if needed:
    $articles = array_filter($nodes, fn($node) => $node->getType() === 'Article');
    

Pro Tips

  • Combine with PHPCR-ODM Criteria: Use globs to narrow results before applying Criteria:
    $candidateNodes = $finder->find('/articles/*');
    $criteria = Criteria::create()
        ->where(Criteria::expr()->eq('published', true));
    $published = $dm->findBy($candidateNodes, $criteria);
    
  • Laravel Artisan Command: Create a command for ad-hoc glob queries:
    // app/Console/Commands/GlobSearch.php
    public function handle() {
        $pattern = $this->argument('pattern');
        $results = app(PhpcrOdmTraversalFinder::class)->find($pattern);
        $this->line("Found " . count($results) . " nodes:");
        foreach ($results as $node) {
            $this->line($node->getPath());
        }
    }
    
    Usage:
    php artisan glob:search "/articles/*"
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor