Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Rector Laravel
https://github.com/driftingly/rector-laravel
Admin
Rector Rules for Laravel automates Laravel upgrades and improves code quality by providing a set of
...
Tokens:
15,460
Snippets:
154
Trust Score:
8.7
Update:
1 week ago
Context
Skills
Chat
Benchmark
91.6
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Rector Laravel - Automated Laravel Refactoring Rules Rector Laravel is a community-driven extension for the Rector PHP automated refactoring tool, providing over 106 rules specifically designed for Laravel applications. It enables automatic code upgrades between Laravel framework versions (5.0 through 13.0), code quality improvements, and migration to modern Laravel patterns. The package supports first-party Laravel packages including Cashier, Livewire, and Faker. The library works by analyzing PHP code using abstract syntax trees (AST) and applying transformation rules to automatically refactor deprecated patterns, upgrade legacy code, and enforce best practices. It integrates with Rector's configuration system and can automatically detect your Laravel version from `composer.json` to apply the appropriate upgrade rules. ## Installation Install the package as a dev dependency. ```bash composer require --dev driftingly/rector-laravel ``` ## Automatic Laravel Version Detection Configure Rector to automatically detect and apply rules based on your Laravel version from composer.json. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetProvider; return RectorConfig::configure() ->withPaths([ __DIR__ . '/app', __DIR__ . '/config', __DIR__ . '/database', __DIR__ . '/routes', __DIR__ . '/tests', ]) ->withSetProviders(LaravelSetProvider::class) ->withComposerBased(laravel: true); ``` ## Manual Laravel Version Configuration Manually specify the target Laravel version using level sets that include all rules for lower versions. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelLevelSetList; return RectorConfig::configure() ->withPaths([ __DIR__ . '/app', ]) ->withSets([ LaravelLevelSetList::UP_TO_LARAVEL_130, ]); // Available level sets: // LaravelLevelSetList::UP_TO_LARAVEL_51 through UP_TO_LARAVEL_130 ``` ## Specific Version Upgrade Rules Apply rules for a specific Laravel version upgrade only (e.g., upgrading from Laravel 12 to Laravel 13). ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([ __DIR__ . '/app', ]) ->withSets([ LaravelSetList::LARAVEL_130, ]); // Available version sets: // LaravelSetList::LARAVEL_50 through LARAVEL_130 ``` ## Code Quality Set Apply Laravel-specific code quality improvements including modern helper functions, facade usage, and best practices. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withSets([ LaravelSetList::LARAVEL_CODE_QUALITY, ]); // Transforms code like: // Before: $app->environment() === 'local' // After: $app->isLocal() // Before: now()->startOfDay() // After: today() // Before: redirect()->back()->with('error', 'msg') // After: back()->with('error', 'msg') // Before: sleep(5) // After: \Illuminate\Support\Sleep::sleep(5) ``` ## Collection Improvements Set Simplify and improve Laravel Collection usage with more readable method calls. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withSets([ LaravelSetList::LARAVEL_COLLECTION, ]); // Transforms code like: // Before: $collection->filter(fn ($n) => ! is_null($n)) // After: $collection->reject(fn ($n) => is_null($n)) // Before: ! $collection->contains($item) // After: $collection->doesntContain($item) // Before: $collection->average() // After: $collection->avg() ``` ## If Helpers Set Convert if statements with abort, report, and throw to Laravel helper functions. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withSets([ LaravelSetList::LARAVEL_IF_HELPERS, ]); // Transforms code like: // Before: // if ($condition) { // abort(404); // } // After: // abort_if($condition, 404); // Before: // if (!$condition) { // throw new Exception(); // } // After: // throw_unless($condition, new Exception()); // Before: // if ($error) { // report(new Exception()); // } // After: // report_if($error, new Exception()); ``` ## Facade to Dependency Injection Set Replace Laravel Facade static calls with proper dependency injection. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withSets([ LaravelSetList::LARAVEL_STATIC_TO_INJECTION, ]); // Transforms code like: // Before: // class SomeController { // public function action() { // $template = view('template.blade'); // } // } // After: // class SomeController { // private \Illuminate\Contracts\View\Factory $viewFactory; // // public function __construct(\Illuminate\Contracts\View\Factory $viewFactory) { // $this->viewFactory = $viewFactory; // } // // public function action() { // $template = $this->viewFactory->make('template.blade'); // } // } ``` ## Factory Improvements Set Modernize Eloquent Factory usage with better IDE support and type safety. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/database/factories']) ->withSets([ LaravelSetList::LARAVEL_FACTORIES, ]); // Transforms code like: // Before: // class UserFactory extends Factory { // protected $model = \App\Models\User::class; // } // After: // /** // * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User> // */ // class UserFactory extends Factory { // protected $model = \App\Models\User::class; // } // Before: $this->faker->name // After: fake()->name ``` ## Legacy Factories to Classes Set Migrate Laravel 7 and earlier closure-based factories to modern class-based factories. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/database/factories']) ->withSets([ LaravelSetList::LARAVEL_LEGACY_FACTORIES_TO_CLASSES, ]); // Transforms code like: // Before (database/factories/UserFactory.php): // $factory->define(App\User::class, function (Faker $faker) { // return [ // 'name' => $faker->name, // 'email' => $faker->unique()->safeEmail, // ]; // }); // After: // class UserFactory extends \Illuminate\Database\Eloquent\Factories\Factory // { // protected $model = App\User::class; // // public function definition() // { // return [ // 'name' => $this->faker->name, // 'email' => $this->faker->unique()->safeEmail, // ]; // } // } ``` ## Eloquent Magic Methods to Query Builder Set Convert Eloquent magic method calls to explicit Query Builder calls for better IDE support. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withSets([ LaravelSetList::LARAVEL_ELOQUENT_MAGIC_METHOD_TO_QUERY_BUILDER, ]); // Transforms code like: // Before: User::first() // After: User::query()->first() // Before: User::where('active', true)->get() // After: User::query()->where('active', true)->get() ``` ## Testing Improvements Set Improve Laravel test code with modern assertions and methods. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/tests']) ->withSets([ LaravelSetList::LARAVEL_TESTING, ]); // Transforms code like: // Before: $response->assertStatus(200) // After: $response->assertOk() // Before: $response->assertStatus(404) // After: $response->assertNotFound() // Before: Carbon::setTestNow('2024-08-11') // After: $this->travelTo('2024-08-11') // Before: $this->json("POST", "/api/users", $data) // After: $this->postJson("/api/users", $data) // Before: $response->assertSee("<li>foo</li>", false) // After: $response->assertSeeHtml("<li>foo</li>") ``` ## Type Declarations Set Add type hints and generic return types for improved type safety. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withSets([ LaravelSetList::LARAVEL_TYPE_DECLARATIONS, ]); // Transforms code like: // Before: // class User extends Model { // public function accounts(): HasMany { // return $this->hasMany(Account::class); // } // } // After: // class User extends Model { // /** @return HasMany<Account> */ // public function accounts(): HasMany { // return $this->hasMany(Account::class); // } // } // Before: $query->where(function ($query) { ... }) // After: $query->where(function (\Illuminate\Contracts\Database\Query\Builder $query) { ... }) ``` ## Configurable Rules Add individual configurable rules with custom settings. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Rector\FuncCall\RemoveDumpDataDeadCodeRector; use RectorLaravel\Rector\StaticCall\RouteActionCallableRector; use RectorLaravel\Rector\MethodCall\WhereToWhereLikeRector; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) // Remove debug statements ->withConfiguredRule(RemoveDumpDataDeadCodeRector::class, [ 'dd', 'dump', 'var_dump', 'print_r' ]) // Convert route strings to callable arrays ->withConfiguredRule(RouteActionCallableRector::class, [ RouteActionCallableRector::NAMESPACE => 'App\\Http\\Controllers', ]) // Convert where LIKE to whereLike (with PostgreSQL support) ->withConfiguredRule(WhereToWhereLikeRector::class, [ WhereToWhereLikeRector::USING_POSTGRES_DRIVER => true, ]); // RemoveDumpDataDeadCodeRector removes: // dd('test'); // dump($variable); // RouteActionCallableRector transforms: // Before: Route::get('/users', 'UserController@index') // After: Route::get('/users', [UserController::class, 'index']) // WhereToWhereLikeRector transforms: // Before: $query->where('name', 'like', '%test%') // After: $query->whereLike('name', '%test%') ``` ## Individual Opinionated Rules Add individual rules that are more opinionated and not included in default sets. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Rector\Class_\RemoveModelPropertyFromFactoriesRector; use RectorLaravel\Rector\MethodCall\ResponseHelperCallToJsonResponseRector; use RectorLaravel\Rector\StaticCall\MinutesToSecondsInCacheRector; use RectorLaravel\Rector\Empty_\EmptyToBlankAndFilledFuncRector; return RectorConfig::configure() ->withPaths([__DIR__ . '/app']) ->withRules([ // Remove $model property from factories (uses naming convention) RemoveModelPropertyFromFactoriesRector::class, // Convert response()->json() to new JsonResponse() ResponseHelperCallToJsonResponseRector::class, // Convert cache minutes to seconds (Laravel 5.8+ change) MinutesToSecondsInCacheRector::class, // Replace empty() with blank()/filled() EmptyToBlankAndFilledFuncRector::class, ]); // ResponseHelperCallToJsonResponseRector transforms: // Before: return response()->json(['key' => 'value']); // After: return new JsonResponse(['key' => 'value']); // MinutesToSecondsInCacheRector transforms: // Before: Cache::put('key', 'value', 60); // After: Cache::put('key', 'value', 60 * 60); // EmptyToBlankAndFilledFuncRector transforms: // Before: empty($value) // After: blank($value) ``` ## Livewire 3.0 Upgrade Set Upgrade Livewire 2.x code to Livewire 3.0 syntax. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\Packages\Livewire\LivewireSetList; return RectorConfig::configure() ->withPaths([__DIR__ . '/app/Livewire']) ->withSets([ LivewireSetList::LIVEWIRE_30, ]); // Transforms code like: // Before: // class MyComponent extends Component { // public string $search = ''; // protected $queryString = ['search']; // // public function getFooBarProperty() { // return 'computed'; // } // } // After: // class MyComponent extends Component { // #[\Livewire\Attributes\Url] // public string $search = ''; // // #[\Livewire\Attributes\Computed] // public function fooBar() { // return 'computed'; // } // } ``` ## Running Rector Execute Rector to apply the configured rules to your codebase. ```bash # Dry run - preview changes without modifying files vendor/bin/rector process --dry-run # Apply changes vendor/bin/rector process # Process specific paths vendor/bin/rector process app/Http/Controllers # Process with specific config file vendor/bin/rector process --config custom-rector.php ``` ## Creating Custom Rules Generate new custom Rector rules using the built-in command. ```bash # Create a basic rule composer make:rule -- MyCustomRuleName # Create a configurable rule composer make:rule -- MyCustomRuleName --configurable # Create rule in subdirectory composer make:rule -- MethodCall/MyMethodCallRule # This generates: # - src/Rector/MyCustomRuleName.php (rule class) # - tests/Rector/MyCustomRuleName/MyCustomRuleNameTest.php # - tests/Rector/MyCustomRuleName/Fixture/some_file.php.inc # - tests/Rector/MyCustomRuleName/config/configured_rule.php ``` ## Complete Configuration Example A comprehensive rector.php configuration combining multiple sets and rules. ```php <?php declare(strict_types=1); use Rector\Config\RectorConfig; use RectorLaravel\Set\LaravelLevelSetList; use RectorLaravel\Set\LaravelSetList; use RectorLaravel\Set\LaravelSetProvider; use RectorLaravel\Rector\FuncCall\RemoveDumpDataDeadCodeRector; return RectorConfig::configure() ->withPaths([ __DIR__ . '/app', __DIR__ . '/config', __DIR__ . '/database', __DIR__ . '/routes', __DIR__ . '/tests', ]) ->withSkip([ __DIR__ . '/app/Legacy/*', __DIR__ . '/tests/fixtures/*', ]) // Auto-detect Laravel version from composer.json ->withSetProviders(LaravelSetProvider::class) ->withComposerBased(laravel: true) // Additional improvement sets ->withSets([ LaravelSetList::LARAVEL_CODE_QUALITY, LaravelSetList::LARAVEL_COLLECTION, LaravelSetList::LARAVEL_IF_HELPERS, LaravelSetList::LARAVEL_TESTING, LaravelSetList::LARAVEL_TYPE_DECLARATIONS, ]) // Configured rules ->withConfiguredRule(RemoveDumpDataDeadCodeRector::class, [ 'dd', 'dump', 'var_dump' ]) // Enable PHP version upgrades ->withPhpSets() // Built-in Rector improvements ->withPreparedSets(deadCode: true, codeQuality: true); ``` ## Summary Rector Laravel provides a comprehensive solution for automated Laravel code refactoring, supporting version upgrades from Laravel 5.0 through 13.0, code quality improvements, and migration to modern patterns. The package integrates seamlessly with Rector's configuration system, allowing both automatic version detection via `composer.json` and manual set selection for precise control over applied rules. Key integration patterns include: using `LaravelSetProvider` with `withComposerBased(laravel: true)` for automatic version detection, combining multiple improvement sets like `LARAVEL_CODE_QUALITY` and `LARAVEL_COLLECTION` for comprehensive refactoring, and adding configurable rules for project-specific needs. The package also supports related Laravel ecosystem packages including Livewire, Cashier, and Faker, making it a complete solution for maintaining modern, clean Laravel codebases through automated refactoring.