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

Ranger Laravel Package

laravel/ranger

Beta Laravel introspection library that walks your codebase and exposes rich DTOs for routes, models, enums, broadcast events, env vars, and Inertia components. Register callbacks per item or collection, then run a single walk to process everything.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/ranger
    

    Add to config/app.php under providers:

    Laravel\Ranger\RangerServiceProvider::class,
    
  2. First Use Case: Inspect all routes in your application:

    use Laravel\Ranger\Ranger;
    
    $ranger = app(Ranger::class);
    $ranger->onRoute(function ($route) {
        echo $route->uri() . "\n";
    });
    $ranger->walk();
    
  3. Where to Look First:

    • Documentation: Focus on the README for basic callbacks.
    • Collectors: Review the supported collectors (routes, models, enums, etc.).
    • DTOs: Check the Laravel\Ranger\Components namespace for detailed DTO structures (e.g., Route, Model).
    • Model Attributes: Pay special attention to $hidden, $visible, and $appends properties in model inspection (new in v0.2.4).

Implementation Patterns

Core Workflows

  1. Model Attribute Inspection: Leverage $hidden, $visible, and $appends in model callbacks:

    $ranger->onModel(function ($model) {
        $this->info('Visible Attributes: ' . implode(', ', $model->visibleAttributes()));
        $this->info('Appended Attributes: ' . implode(', ', $model->appendedAttributes()));
    });
    
  2. Component-Specific Callbacks: Register callbacks for granular control over individual components:

    $ranger->onModel(function ($model) {
        // Log model attributes (respecting $hidden/$visible)
        file_put_contents('models.log', $model->name() . ': ' . implode(', ', $model->getVisibleAttributes()), FILE_APPEND);
    });
    
  3. Bulk Processing: Use collection callbacks for post-processing after all components are discovered:

    $ranger->onModels(function (Collection $models) {
        $models->each(function ($model) {
            // Generate API docs from models, respecting $appends
            $this->info($model->name() . ' - Appends: ' . $model->appendedAttributes());
        });
    });
    

Integration Tips

  1. Artisan Command: Encapsulate Ranger in a custom Artisan command for CLI usage:

    use Laravel\Ranger\Ranger;
    use Illuminate\Console\Command;
    
    class ModelInspectCommand extends Command
    {
        protected $signature = 'app:inspect-models';
        protected $description = 'Inspect models with hidden/visible/appends';
    
        public function handle(Ranger $ranger)
        {
            $ranger->onModel(fn($model) => $this->info(
                $model->name() . ': ' .
                implode(', ', $model->getVisibleAttributes())
            ));
            $ranger->walk();
        }
    }
    
  2. Event Listeners: Trigger Ranger during application bootstrapping (e.g., booted event):

    use Laravel\Ranger\Ranger;
    
    public function booted()
    {
        $ranger = app(Ranger::class);
        $ranger->onModels(fn($models) => $this->cacheModelAttributes($models));
        $ranger->walk();
    }
    
  3. Testing: Use Ranger in PHPUnit tests to validate model attributes:

    public function testModelVisibility()
    {
        $ranger = app(Ranger::class);
        $ranger->onModel(function ($model) {
            $this->assertNotContains('password', $model->getVisibleAttributes());
            $this->assertContains('api_token', $model->appendedAttributes());
        });
        $ranger->walk();
    }
    
  4. Dynamic Configuration: Load callbacks from config files:

    $callbacks = config('ranger.callbacks');
    foreach ($callbacks as $type => $callback) {
        $method = 'on' . ucfirst($type);
        $ranger->$method($callback);
    }
    

Gotchas and Tips

Pitfalls

  1. Performance:

    • Ranger scans the entire application. Avoid running it in production or during high-traffic periods.
    • Mitigation: Use --env=testing or cache results:
      $ranger->walk()->cache()->forever();
      
  2. Model Attribute Resolution:

    • $hidden and $visible properties now override default attribute visibility (v0.2.4).
    • Tip: Use getVisibleAttributes() and appendedAttributes() methods for consistency:
      $ranger->onModel(function ($model) {
          $this->info('Visible: ' . implode(', ', $model->getVisibleAttributes()));
      });
      
  3. Route URI Resolution:

    • Relative URIs (e.g., Route::domain('admin')->group(...)) may not resolve as expected.
    • Fix: Ensure APP_URL is set correctly in .env or use absolute paths:
      $ranger->onRoute(function ($route) {
          $this->info($route->uri()); // Uses APP_URL + base_path()
      });
      
  4. Inertia.js Quirks:

    • Shared props or components in subdirectories may not be detected.
    • Workaround: Explicitly register paths:
      $ranger->onInertiaComponent(function ($component) {
          if (str_contains($component->path(), 'Resources/Pages')) {
              // Process custom Inertia components
          }
      });
      
  5. Environment Variables:

    • Sensitive variables (e.g., APP_KEY) may leak if not filtered.
    • Solution: Sanitize output:
      $ranger->onEnv(function ($env) {
          if (str_contains($env->key(), ['KEY', 'SECRET'])) {
              return; // Skip sensitive vars
          }
          $this->info($env->key() . '=' . $env->value());
      });
      

Debugging Tips

  1. Verbose Output: Enable debug mode for detailed logs:

    $ranger->debug(true)->walk();
    
  2. Model Attribute Validation: Validate model attributes with visibility rules:

    public function testModelVisibility()
    {
        $ranger = app(Ranger::class);
        $ranger->onModel(function ($model) {
            $this->assertNotContains('password', $model->getVisibleAttributes());
            $this->assertContains('api_token', $model->appendedAttributes());
        });
        $ranger->walk();
    }
    
  3. Partial Walks: Use only() to inspect specific collectors:

    $ranger->only(['routes', 'models'])->walk();
    
  4. Excluding Directories: Skip vendor or test directories:

    $ranger->ignoreDirectories(['vendor', 'tests'])->walk();
    

Extension Points

  1. Custom Collectors: Extend Ranger by creating a custom collector:

    use Laravel\Ranger\Collector;
    
    class CustomCollector implements Collector
    {
        public function collect()
        {
            return collect([new CustomComponent('data')]);
        }
    }
    

    Register it in RangerServiceProvider:

    public function register()
    {
        $this->app->singleton(Ranger::class, function ($app) {
            $ranger = new Ranger();
            $ranger->addCollector(new CustomCollector());
            return $ranger;
        });
    }
    
  2. DTO Customization: Override DTO properties in callbacks:

    $ranger->onRoute(function ($route) {
        $route->setMetadata(['tags' => ['api']]);
    });
    
  3. Post-Walk Processing: Chain methods after walk():

    $results = $ranger->walk()->getResults();
    $results['models']->each(function ($model) {
        $this->info($model->name() . ': ' . implode(', ', $model->getVisibleAttributes()));
    });
    
  4. Model Attribute Inspection: Create custom inspection methods for models:

    $ranger->onModel(function ($model) {
        $this->info('Full Attributes: ' . implode(', ', $model->getAttributes()));
        $this->info('Visible Attributes: ' . implode(', ', $model->getVisibleAttributes()));
        $this->info('Appended Attributes: ' . implode(', ', $model->appendedAttributes()));
    });
    
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.
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
anil/file-picker
broqit/fields-ai