Intention Actions
Laravel Idea provides a set of intention actions — quick code transformations available via Alt+Enter (or ⌥Enter on macOS) when your cursor is on the relevant code.
Promote Request to FormRequest
Trigger: cursor on an Illuminate\Http\Request parameter in a controller method.
This intention extracts all validation rules found in the current method into a new FormRequest class. After the refactoring:
- The parameter type is updated to the new
FormRequestclass. - Inline
$request->validate([...])calls are removed or replaced with$request->safe(). - The generated class is opened/placed according to your Code Generation settings.
Before:
public function store(Request $request)
{
$data = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email',
]);
// ...
}After:
public function store(StoreUserRequest $request)
{
$data = $request->safe();
// ...
}Generated FormRequest:
class StoreUserRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email'],
];
}
}Note: If the validation rules contain references to external variables or method calls, the plugin will warn you before proceeding. You will need to fix those references manually.
Convert Facade alias to Facade call
Trigger: cursor on a facade alias (e.g., Cache, Auth, DB) that is registered as a global alias in your Laravel application.
Replaces all uses of the alias within the current method with the fully-qualified facade class reference and inserts the corresponding use statement.
Before:
Cache::put('key', $value, 60);
Cache::get('key');After:
use Illuminate\Support\Facades\Cache;
Cache::put('key', $value, 60);
Cache::get('key');Convert Facade call to Dependency
Trigger: cursor on a facade class reference (e.g., Cache, Illuminate\Support\Facades\Cache) inside a method.
Replaces all static facade calls in the current method with calls on an injected dependency. A popup lets you choose whether to inject it:
- Into the constructor (adds a promoted constructor property).
- Into the current method (adds a typed parameter).
The plugin analyses which facade methods are used and picks the best matching interface or concrete class.
Before:
public function handle()
{
Cache::put('key', $value, 60);
Cache::get('key');
}After (constructor injection):
public function __construct(
private readonly CacheRepository $cache,
) {}
public function handle()
{
$this->cache->put('key', $value, 60);
$this->cache->get('key');
}Requirement: Constructor property promotion must be enabled in Laravel Idea settings.
Move dependency to constructor
Trigger: cursor on a typed (non-primitive) parameter in a non-static, non-magic method.
Moves the parameter to the class constructor as a promoted property and replaces all local uses of the variable with $this->propertyName.
If the same parameter signature exists in multiple methods of the class, a popup appears asking whether to apply the change to just the current method or to all matching methods.
Before:
public function process(UserRepository $userRepository): void
{
$userRepository->find($id);
}After:
public function __construct(
private readonly UserRepository $userRepository,
) {}
public function process(): void
{
$this->userRepository->find($id);
}Requirement: Constructor property promotion must be enabled in Laravel Idea settings.
Convert validation string to array
Trigger: cursor on a pipe-separated validation rule string (e.g., "required|email|max:255").
Converts the string to an equivalent PHP array, which is the modern recommended style.
Before:
'email' => 'required|email|max:255',After:
'email' => ['required', 'email', 'max:255'],Convert all validation strings to array
Trigger: cursor on any pipe-separated validation rule string inside a validation rules() array.
The same conversion as above but applied to every field in the surrounding array at once.
Before:
[
'name' => 'required|string|max:255',
'email' => 'required|email',
'age' => 'nullable|integer|min:0',
];After:
[
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email'],
'age' => ['nullable', 'integer', 'min:0'],
];Convert validation rule to the Rule object
Trigger: cursor on a string validation rule that has a corresponding Rule:: factory method. Supported rules: unique, exists, in, not_in, array, file, image, dimensions.
Converts the string form to the fluent Rule:: object API and inserts the required use statement.
Before:
'email' => ['required', 'unique:users,email'],After:
use Illuminate\Validation\Rule;
'email' => ['required', Rule::unique('users', 'email')]Other examples:
| Before | After |
|---|---|
'in:active,inactive' | Rule::in(['active', 'inactive']) |
'dimensions:width=100,height=200' | Rule::dimensions()->width(100)->height(200) |
'image' | Rule::imageFile() |
Convert to [Controller::class] call
Trigger: cursor on a string-based controller reference in a route definition (e.g., "UserController@index").
Converts the legacy string format to the modern class-constant array syntax and inserts the use statement for the controller class.
Before:
Route::get('/users', 'UserController@index');
Route::post('/users', 'App\Http\Controllers\UserController');After:
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', UserController::class);Convert all controller calls
Trigger: cursor on any string-based controller reference in a route file.
Same conversion as above, applied to every string-based controller reference in the entire file.
Convert Eloquent scope to #[Scope]
Trigger: cursor on a method name that starts with scope inside an Eloquent model class (Laravel 12.6+ project with #[Scope] attribute syntax enabled).
Migrates the old naming convention-based scope to the new PHP attribute syntax:
- Removes the
scopeprefix from the method name. - Adds the
#[Scope]attribute. - Changes the method visibility to
protectedif it waspublic.
Before:
public function scopeActive(Builder $query): void
{
$query->where('active', true);
}After:
use Illuminate\Database\Eloquent\Attributes\Scope;
#[Scope]
protected function active(Builder $query): void
{
$query->where('active', true);
}Note: This intention is only available when the project's Laravel version supports the
#[Scope]attribute syntax (configurable in Laravel Idea settings).
Convert all Eloquent scopes to #[Scope]
Trigger: cursor on any scope* method inside an Eloquent model.
Same conversion as above, applied to every scope* method in the current model class.
Convert Blade braces
{{ }} → {!! !!}
Trigger: cursor inside {{ ... }} braces in a Blade template.
Converts HTML-escaped output braces to unescaped output braces. Use this when you intentionally want to output raw HTML.
Before:
{{ $htmlContent }}After:
{!! $htmlContent !!}Warning: Unescaped output is only safe if the content is trusted. Prefer
for user-supplied data to prevent XSS.
{!! !!} → {{ ... }}
Trigger: cursor inside {!! ... !!} braces in a Blade template.
Converts unescaped output back to HTML-escaped output.
Before:
{!! $htmlContent !!}After:
{{ $htmlContent }}Convert to @class directive
Trigger: cursor inside a class="..." attribute that contains multiple space-separated CSS classes (in a Blade template).
Converts a static multi-class attribute to Blade's @class([...]) directive, placing each class on its own line so conditional classes can be added easily.
Before:
<div class="flex items-center gap-4">After:
<div @class([
'flex',
'items-center',
'gap-4',
])>Requirement: The project's Laravel version must support the
@classdirective (Laravel 9+).
Wrap with @class directive
Trigger: cursor inside a class="..." attribute in a Blade template.
Wraps the existing class attribute value inside the @class([...]) directive as a single string entry, giving you a starting point to add conditional class expressions.
Before:
<div class="btn-primary">After:
<div @class(['btn-primary'])>