Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 56 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,65 @@ return RectorConfig::configure()
| Set | Purpose |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [LaravelSetList::LARAVEL_ARRAYACCESS_TO_METHOD_CALL](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-arrayaccess-to-method-call.php) | Converts uses of things like `$app['config']` to `$app->make('config')`. |
| [LaravelSetList::LARAVEL_ARRAY_STR_FUNCTION_TO_STATIC_CALL](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-array-str-functions-to-static-call.php) | Converts most string and array helpers into Str and Arr Facades' static calls.<br/>https://laravel.com/docs/12.x/facades#facades-vs-helper-functions |
| [LaravelSetList::LARAVEL_ARRAY_STR_FUNCTION_TO_STATIC_CALL](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-array-str-functions-to-static-call.php) | Converts most string and array helpers into Str and Arr Facades' static calls.<br/><https://laravel.com/docs/12.x/facades#facades-vs-helper-functions> |
| [LaravelSetList::LARAVEL_CODE_QUALITY](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-code-quality.php) | Replaces magical call on `$this->app["something"]` to standalone variable with PHPDocs. |
| [LaravelSetList::LARAVEL_COLLECTION](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-collection.php) | Improves the usage of Laravel Collections by using simpler, more efficient, or more readable methods. |
| [LaravelSetList::LARAVEL_CONTAINER_STRING_TO_FULLY_QUALIFIED_NAME](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-container-string-to-fully-qualified-name.php) | Changes the string or class const used for a service container make call.<br/>https://laravel.com/docs/12.x/container#the-make-method |
| [LaravelSetList::LARAVEL_ELOQUENT_MAGIC_METHOD_TO_QUERY_BUILDER](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-eloquent-magic-method-to-query-builder.php) | Transforms magic method calls on Eloquent Models into corresponding Query Builder method calls.<br/>https://laravel.com/docs/12.x/eloquent |
| [LaravelSetList::LARAVEL_FACADE_ALIASES_TO_FULL_NAMES](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-facade-aliases-to-full-names.php) | Replaces Facade aliases with full Facade names.<br/>https://laravel.com/docs/12.x/facades#facade-class-reference |
| [LaravelSetList::LARAVEL_CONTAINER_STRING_TO_FULLY_QUALIFIED_NAME](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-container-string-to-fully-qualified-name.php) | Changes the string or class const used for a service container make call.<br/><https://laravel.com/docs/12.x/container#the-make-method> |
| [LaravelSetList::LARAVEL_ELOQUENT_MAGIC_METHOD_TO_QUERY_BUILDER](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-eloquent-magic-method-to-query-builder.php) | Transforms magic method calls on Eloquent Models into corresponding Query Builder method calls.<br/><https://laravel.com/docs/12.x/eloquent> |
| [LaravelSetList::LARAVEL_FACADE_ALIASES_TO_FULL_NAMES](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-facade-aliases-to-full-names.php) | Replaces Facade aliases with full Facade names.<br/><https://laravel.com/docs/12.x/facades#facade-class-reference> |
| [LaravelSetList::LARAVEL_FACTORIES](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-factories.php) | Makes working with Laravel Factories easier and more IDE friendly. |
| [LaravelSetList::LARAVEL_IF_HELPERS](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-if-helpers.php) | Replaces `abort()`, `report()`, `throw` statements inside conditions with `abort_if()`, `report_if()`, `throw_if()` function calls.<br/>https://laravel.com/docs/12.x/helpers#method-abort-if |
| [LaravelSetList::LARAVEL_LEGACY_FACTORIES_TO_CLASSES](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-legacy-factories-to-classes.php) | Migrates Eloquent legacy model factories (with closures) into class based factories.<br/>https://laravel.com/docs/8.x/releases#model-factory-classes |
| [LaravelSetList::LARAVEL_STATIC_TO_INJECTION](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-static-to-injection.php) | Replaces Laravel's Facades with Dependency Injection.<br/>https://tomasvotruba.com/blog/2019/03/04/how-to-turn-laravel-from-static-to-dependency-injection-in-one-day/<br/>https://laravel.com/docs/12.x/facades#facades-vs-dependency-injection |
| [LaravelSetList::LARAVEL_IF_HELPERS](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-if-helpers.php) | Replaces `abort()`, `report()`, `throw` statements inside conditions with `abort_if()`, `report_if()`, `throw_if()` function calls.<br/><https://laravel.com/docs/12.x/helpers#method-abort-if> |
| [LaravelSetList::LARAVEL_LEGACY_FACTORIES_TO_CLASSES](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-legacy-factories-to-classes.php) | Migrates Eloquent legacy model factories (with closures) into class based factories.<br/><https://laravel.com/docs/8.x/releases#model-factory-classes> |
| [LaravelSetList::LARAVEL_STATIC_TO_INJECTION](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-static-to-injection.php) | Replaces Laravel's Facades with Dependency Injection.<br/><https://tomasvotruba.com/blog/2019/03/04/how-to-turn-laravel-from-static-to-dependency-injection-in-one-day/><br/><https://laravel.com/docs/12.x/facades#facades-vs-dependency-injection> |
| [LaravelSetList::LARAVEL_TESTING](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-testing.php) | Improves Laravel testing by converting deprecated methods and adding better assertions. |
| [LaravelSetList::LARAVEL_TYPE_DECLARATIONS](https://github.com/driftingly/rector-laravel/blob/main/config/sets/laravel-type-declarations.php) | Adds type hints and generic return types to improve Laravel code type safety. |

## Configurable Rules

These rules require configuration and must be added manually to your `rector.php` file.

```php
<?php declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Rector\FuncCall\RemoveDumpDataDeadCodeRector;

return RectorConfig::configure()
->withConfiguredRule(RemoveDumpDataDeadCodeRector::class, [
'dd', 'dump', 'var_dump'
]);
```

| Rule | Description |
|------|-------------|
| [RemoveDumpDataDeadCodeRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/FuncCall/RemoveDumpDataDeadCodeRector.php) | Removes debug function calls like `dd()`, `dump()`, etc. from code. Configure with an array of function names to remove (default: `['dd', 'dump']`). |
| [RouteActionCallableRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/StaticCall/RouteActionCallableRector.php) | Converts route action strings like `'UserController@index'` to callable arrays `[UserController::class, 'index']`. Configure with `NAMESPACE` for controller namespace and `ROUTES` for file-specific namespaces. |
| [WhereToWhereLikeRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/MethodCall/WhereToWhereLikeRector.php) | Converts `where('column', 'like', 'value')` to `whereLike('column', 'value')` calls. Configure with `USING_POSTGRES_DRIVER` boolean to handle PostgreSQL vs MySQL differences. |

## Opinionated Rules

These rules are more opinionated and are not included in any sets by default.

```php
<?php declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Rector\MethodCall\ResponseHelperCallToJsonResponseRector;

return RectorConfig::configure()
->withRules([
ResponseHelperCallToJsonResponseRector::class,
]);
```

| Rule | Description |
|------|-------------|
| [RemoveModelPropertyFromFactoriesRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/Class_/RemoveModelPropertyFromFactoriesRector.php) | Removes the `$model` property from Factories. |
| [ResponseHelperCallToJsonResponseRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/MethodCall/ResponseHelperCallToJsonResponseRector.php) | Converts `response()->json()` to `new JsonResponse()`. |
| [MinutesToSecondsInCacheRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/StaticCall/MinutesToSecondsInCacheRector.php) | Change minutes argument to seconds in cache methods. |
| [UseComponentPropertyWithinCommandsRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/MethodCall/UseComponentPropertyWithinCommandsRector.php) | Use `$this->components` property within commands. |
| [UseForwardsCallsTraitRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/Class_/UseForwardsCallsTraitRector.php) | Replaces the use of `call_user_func` and `call_user_func_array` method with the CallForwarding trait. |
| [EmptyToBlankAndFilledFuncRector](https://github.com/driftingly/rector-laravel/blob/main/src/Rector/Empty_/EmptyToBlankAndFilledFuncRector.php) | Converts `empty()` to `blank()` and `filled()` |

## Creating New Rules

Expand Down
36 changes: 36 additions & 0 deletions config/sets/laravel-code-quality.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,29 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Rector\ArrayDimFetch\EnvVariableToEnvHelperRector;
use RectorLaravel\Rector\ArrayDimFetch\RequestVariablesToRequestFacadeRector;
use RectorLaravel\Rector\ArrayDimFetch\ServerVariableToRequestFacadeRector;
use RectorLaravel\Rector\ArrayDimFetch\SessionVariableToSessionFacadeRector;
use RectorLaravel\Rector\Assign\CallOnAppArrayAccessToStandaloneAssignRector;
use RectorLaravel\Rector\Class_\AnonymousMigrationsRector;
use RectorLaravel\Rector\ClassMethod\MakeModelAttributesAndScopesProtectedRector;
use RectorLaravel\Rector\Coalesce\ApplyDefaultInsteadOfNullCoalesceRector;
use RectorLaravel\Rector\Expr\AppEnvironmentComparisonToParameterRector;
use RectorLaravel\Rector\Expr\SubStrToStartsWithOrEndsWithStaticMethodCallRector\SubStrToStartsWithOrEndsWithStaticMethodCallRector;
use RectorLaravel\Rector\FuncCall\NotFilledBlankFuncCallToBlankFilledFuncCallRector;
use RectorLaravel\Rector\FuncCall\NowFuncWithStartOfDayMethodCallToTodayFuncRector;
use RectorLaravel\Rector\FuncCall\RemoveRedundantValueCallsRector;
use RectorLaravel\Rector\FuncCall\RemoveRedundantWithCallsRector;
use RectorLaravel\Rector\FuncCall\SleepFuncToSleepStaticCallRector;
use RectorLaravel\Rector\FuncCall\ThrowIfAndThrowUnlessExceptionsToUseClassStringRector;
use RectorLaravel\Rector\MethodCall\EloquentOrderByToLatestOrOldestRector;
use RectorLaravel\Rector\MethodCall\RedirectBackToBackHelperRector;
use RectorLaravel\Rector\MethodCall\RedirectRouteToToRouteHelperRector;
use RectorLaravel\Rector\MethodCall\ReverseConditionableMethodCallRector;
use RectorLaravel\Rector\MethodCall\ValidationRuleArrayStringValueToArrayRector;
use RectorLaravel\Rector\PropertyFetch\OptionalToNullsafeOperatorRector;
use RectorLaravel\Rector\StaticCall\DispatchToHelperFunctionsRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->import(__DIR__ . '/../config.php');
Expand All @@ -16,4 +34,22 @@
$rectorConfig->rule(ApplyDefaultInsteadOfNullCoalesceRector::class);
$rectorConfig->rule(MakeModelAttributesAndScopesProtectedRector::class);
$rectorConfig->rule(AppEnvironmentComparisonToParameterRector::class);
$rectorConfig->rule(ThrowIfAndThrowUnlessExceptionsToUseClassStringRector::class);
$rectorConfig->rule(EnvVariableToEnvHelperRector::class);
$rectorConfig->rule(RequestVariablesToRequestFacadeRector::class);
$rectorConfig->rule(ServerVariableToRequestFacadeRector::class);
$rectorConfig->rule(SessionVariableToSessionFacadeRector::class);
$rectorConfig->rule(SubStrToStartsWithOrEndsWithStaticMethodCallRector::class);
$rectorConfig->rule(NowFuncWithStartOfDayMethodCallToTodayFuncRector::class);
$rectorConfig->rule(RemoveRedundantValueCallsRector::class);
$rectorConfig->rule(RemoveRedundantWithCallsRector::class);
$rectorConfig->rule(OptionalToNullsafeOperatorRector::class);
$rectorConfig->rule(ValidationRuleArrayStringValueToArrayRector::class);
$rectorConfig->rule(RedirectBackToBackHelperRector::class);
$rectorConfig->rule(RedirectRouteToToRouteHelperRector::class);
$rectorConfig->rule(AnonymousMigrationsRector::class);
$rectorConfig->rule(SleepFuncToSleepStaticCallRector::class);
$rectorConfig->rule(DispatchToHelperFunctionsRector::class);
$rectorConfig->rule(NotFilledBlankFuncCallToBlankFilledFuncCallRector::class);
$rectorConfig->rule(EloquentOrderByToLatestOrOldestRector::class);
};
17 changes: 17 additions & 0 deletions config/sets/laravel-testing.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Rector\MethodCall\AssertStatusToAssertMethodRector;
use RectorLaravel\Rector\MethodCall\JsonCallToExplicitJsonCallRector;
use RectorLaravel\Rector\StaticCall\AssertWithClassStringToTypeHintedClosureRector;
use RectorLaravel\Rector\StaticCall\CarbonSetTestNowToTravelToRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->import(__DIR__ . '/../config.php');
$rectorConfig->rule(JsonCallToExplicitJsonCallRector::class);
$rectorConfig->rule(AssertStatusToAssertMethodRector::class);
$rectorConfig->rule(AssertWithClassStringToTypeHintedClosureRector::class);
$rectorConfig->rule(CarbonSetTestNowToTravelToRector::class);
};
17 changes: 17 additions & 0 deletions config/sets/laravel-type-declarations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Rector\ClassMethod\AddGenericReturnTypeToRelationsRector;
use RectorLaravel\Rector\FuncCall\TypeHintTappableCallRector;
use RectorLaravel\Rector\MethodCall\EloquentWhereRelationTypeHintingParameterRector;
use RectorLaravel\Rector\MethodCall\EloquentWhereTypeHintClosureParameterRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->import(__DIR__ . '/../config.php');
$rectorConfig->rule(TypeHintTappableCallRector::class);
$rectorConfig->rule(AddGenericReturnTypeToRelationsRector::class);
$rectorConfig->rule(EloquentWhereRelationTypeHintingParameterRector::class);
$rectorConfig->rule(EloquentWhereTypeHintClosureParameterRector::class);
};
14 changes: 14 additions & 0 deletions config/sets/lumen.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Rector\MethodCall\LumenRoutesStringActionToUsesArrayRector;
use RectorLaravel\Rector\MethodCall\LumenRoutesStringMiddlewareToArrayRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->import(__DIR__ . '/../config.php');

$rectorConfig->rule(LumenRoutesStringActionToUsesArrayRector::class);
$rectorConfig->rule(LumenRoutesStringMiddlewareToArrayRector::class);
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class EloquentOrderByToLatestOrOldestRector extends AbstractRector implements Co
/**
* @var string[]
*/
private array $allowedPatterns = [];
private array $allowedPatterns = ['*_at', '*_date', '*_on'];

public function __construct(private readonly QueryBuilderAnalyzer $queryBuilderAnalyzer) {}

Expand Down
6 changes: 6 additions & 0 deletions src/Set/LaravelSetList.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,10 @@ final class LaravelSetList
final public const string LARAVEL_LEGACY_FACTORIES_TO_CLASSES = __DIR__ . '/../../config/sets/laravel-legacy-factories-to-classes.php';

final public const string LARAVEL_STATIC_TO_INJECTION = __DIR__ . '/../../config/sets/laravel-static-to-injection.php';

final public const string LARAVEL_TESTING = __DIR__ . '/../../config/sets/laravel-testing.php';

final public const string LARAVEL_TYPE_DECLARATIONS = __DIR__ . '/../../config/sets/laravel-type-declarations.php';

final public const string LUMEN = __DIR__ . '/../../config/sets/lumen.php';
}