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

Surveyor Laravel Package

laravel/surveyor

Beta Laravel tool for mostly static analysis of PHP/Laravel apps. Parses files/classes to extract rich metadata (classes, methods, properties, types) and can inspect models and container bindings for extra detail. Returns structured results for other tools.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laravel/surveyor
    

    No additional configuration is required for basic usage.

  2. First Use Case: Run Surveyor on a directory (e.g., app/) to extract metadata:

    use Laravel\Surveyor\Surveyor;
    
    $surveyor = new Surveyor();
    $results = $surveyor->survey(app_path('Http/Controllers'));
    

    This returns an array of Surveyor\Result objects, each representing a parsed PHP file. Key Improvements in v0.2.4:

    • Now correctly analyzes interfaces alongside classes.
    • Fixed method resolution for names that conflict with PHP type keywords (e.g., int, string).
    • Improved Eloquent builder method resolution, including support for integer range types and generics propagation through method chains.
  3. Where to Look First:

    • Surveyor class: Core entry point for analysis (now handles interfaces and complex type resolution).
    • Result class: Contains parsed metadata (e.g., classes, interfaces, methods, properties).
    • Surveyor::survey(): Primary method to trigger analysis (now more accurate for Eloquent builders).
    • Surveyor::getResults(): Retrieve raw results (useful for debugging).

Implementation Patterns

Core Workflows

  1. Surveying a Directory (Including Interfaces):

    $results = Surveyor::survey(base_path('app'));
    foreach ($results as $result) {
        // Access parsed data: $result->classes, $result->interfaces, $result->methods, etc.
        if (isset($result->interfaces)) {
            // Handle interface-specific logic.
        }
    }
    

    Tip: The improved handling of interfaces and Eloquent builders ensures accurate parsing of abstract contracts and query methods.

  2. Filtering Results by Type: Use Surveyor::filter() to narrow results (e.g., by namespace, class name, or interface):

    $filtered = $results->filter(fn ($result) =>
        str_contains($result->namespace, 'App\\Contracts') ||
        (isset($result->interfaces) && !empty($result->interfaces))
    );
    
  3. Extracting Eloquent Builder Metadata: Access structured data for Eloquent builders (now with generics and integer range support):

    foreach ($results as $result) {
        $builderMethods = $result->methods
            ->where('name', 'like', 'where%')
            ->where('returnType', 'contains', 'Builder');
        $rangeMethods = $result->methods
            ->where('parameters', 'contains', ['type' => 'int[]']);
    }
    
  4. Integration with Laravel Ranger: For high-level DTOs, pair with laravel/ranger:

    use Laravel\Ranger\Ranger;
    
    $ranger = new Ranger();
    $ranger->analyze($results); // Convert Surveyor results to Ranger DTOs (now includes interfaces).
    

Integration Tips

  • Artisan Command: Create a custom command to run Surveyor periodically (e.g., during CI):

    use Laravel\Surveyor\Surveyor;
    use Symfony\Component\Console\Command\Command;
    
    class SurveyCommand extends Command {
        protected function handle() {
            $results = Surveyor::survey(app_path());
            // Log or process results, including interfaces and Eloquent builders.
        }
    }
    
  • Event Listeners: Trigger Surveyor on file changes (e.g., via file:updated events) to keep metadata fresh, especially for interfaces and builders.

  • Caching: Cache results for performance (e.g., in bootstrap/cache):

    $cacheKey = 'surveyor_results';
    $results = Cache::remember($cacheKey, now()->addHours(1), fn () => Surveyor::survey(app_path()));
    

    Note: Corrupted cache files are treated as cache misses (v0.2.3), ensuring stale data is not returned.


Gotchas and Tips

Pitfalls

  1. Beta API Instability:

    • The API may change before v1.0.0. Check the changelog for breaking changes.
    • Workaround: Pin the package version in composer.json (e.g., ^0.2.0) to avoid unexpected updates.
  2. Performance with Large Codebases:

    • Surveyor is not optimized for real-time analysis of thousands of files. Use caching or run during off-peak hours.
    • Tip: Exclude directories like vendor/ or storage/ to speed up analysis:
      $surveyor = new Surveyor(['exclude' => ['vendor', 'storage']]);
      
  3. False Positives in Parsing:

    • While improved in v0.2.4, Surveyor may still misinterpret dynamic code (e.g., eval(), create_function) or complex inline assignments.
    • Tip: Manually verify critical results (e.g., method signatures) in edge cases, especially for interfaces or Eloquent builders.
  4. Namespace Resolution:

    • Surveyor may not resolve namespaces correctly if autoloading is misconfigured. Ensure composer dump-autoload is up to date.
    • New in v0.2.4: Fixed method resolution for names conflicting with PHP type keywords (e.g., int, string).
  5. Eloquent Builder Method Resolution:

    • New in v0.2.4: Surveyor now correctly resolves Eloquent builder methods, including generics propagation and integer range types.
    • Tip: Test queries involving complex builder chains (e.g., whereBetween, orWhere) to ensure accurate type resolution.

Debugging

  • Enable Verbose Output: Pass ['verbose' => true] to the Surveyor constructor to log parsing details:

    $surveyor = new Surveyor(['verbose' => true]);
    
  • Inspect Raw Results: Use Surveyor::getRawResults() to debug parsing issues:

    $rawResults = Surveyor::getRawResults();
    dd($rawResults); // Inspect the underlying data structure, including interfaces and builders.
    

Extension Points

  1. Custom Analyzers for Interfaces: Extend Surveyor to analyze interfaces (e.g., detect unimplemented methods):

    use Laravel\Surveyor\Contracts\Analyzer;
    
    class InterfaceAnalyzer implements Analyzer {
        public function analyze($result) {
            if (isset($result->interfaces)) {
                foreach ($result->interfaces as $interface) {
                    // Check for unimplemented methods or deprecated interfaces.
                }
            }
        }
    }
    

    Register the analyzer via the Surveyor constructor:

    $surveyor = new Surveyor(['analyzers' => [new InterfaceAnalyzer()]]);
    
  2. Post-Processing for Eloquent Builders: Use Laravel collections to transform builder-related results:

    $builderMethods = $results->flatMap->methods
        ->where('returnType', 'contains', 'Builder')
        ->where('parameters', '!=', []);
    
  3. Integration with Static Analysis Tools: Export Surveyor results to JSON for use with other tools (e.g., SonarQube):

    file_put_contents(
        storage_path('app/surveyor_results.json'),
        json_encode($results->toArray())
    );
    

    Note: Results now include interfaces and refined Eloquent builder metadata.

Config Quirks

  • Exclusion Patterns: Use glob patterns to exclude files/directories:

    $surveyor = new Surveyor(['exclude' => ['tests/*', 'app/Console/*']]);
    
  • File Extensions: Surveyor defaults to .php files. To include other extensions (e.g., .inc), pass:

    $surveyor = new Surveyor(['extensions' => ['php', 'inc']]);
    
  • Handling PHP Type Keywords: New in v0.2.4: Surveyor now correctly resolves method names that conflict with PHP type keywords (e.g., int, string). No additional configuration is required.

  • Eloquent Builder Generics: New in v0.2.4: Surveyor propagates generics through Eloquent builder method chains. Ensure your codebase uses modern Laravel syntax for optimal parsing.

  • Cache Handling: New in v0.2.3: Corrupted disk cache files are automatically treated as cache misses, preventing stale data from being returned. No additional configuration is required.

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