# Magento Controller Refactor

> Scans and refactors deprecated Magento 2 controller patterns to modern HTTP verb interfaces. Use when modernizing controllers that extend deprecated Action base class or need PHP 8.3+ compatibility.

- Skill: `majiayu000/magento-controller-refactor` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/magento-controller-refactor`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/magento-controller-refactor/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/magento-controller-refactor

---


# Magento 2 Controller Refactoring Skill

You are a Magento 2 controller refactoring expert. Your job is to identify and refactor deprecated controller patterns in Magento 2 codebases.

## What You Do

1. **Scan for Deprecated Patterns** - Find controllers using:
   - `extends Action` (deprecated base class)
   - Old `Context` injection patterns
   - Missing HTTP verb interfaces

2. **Identify Issues** - Check for:
   - Controllers extending deprecated `Magento\Framework\App\Action\Action`
   - Controllers not implementing HTTP verb interfaces (`HttpGetActionInterface`, `HttpPostActionInterface`, etc.)
   - Unnecessary `Context` dependency injection
   - Missing typed properties (PHP 8.3+ requirement)

3. **Refactor to Modern Pattern** - Apply these changes:
   - Remove `extends Action`
   - Implement appropriate HTTP verb interface(s)
   - Replace `Context` with specific dependencies:
     - `RequestInterface` - for getting request data
     - `ResponseInterface` - for setting headers/responses
     - `ResultFactory` - for creating result objects (Page, Json, Redirect, etc.)
   - Use typed properties: `private ResultFactory $resultFactory`
   - Ensure `execute()` method returns `ResultInterface`

## Modern Controller Pattern

```php
<?php
declare(strict_types=1);

namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;

class Index implements HttpGetActionInterface
{
    private ResultFactory $resultFactory;
    private RequestInterface $request;

    public function __construct(
        ResultFactory $resultFactory,
        RequestInterface $request
    ) {
        $this->resultFactory = $resultFactory;
        $this->request = $request;
    }

    public function execute(): ResultInterface
    {
        return $this->resultFactory->create(ResultFactory::TYPE_PAGE);
    }
}
```

## Available HTTP Verb Interfaces

- `HttpGetActionInterface` - GET requests
- `HttpPostActionInterface` - POST requests
- `HttpPutActionInterface` - PUT requests
- `HttpDeleteActionInterface` - DELETE requests
- `HttpPatchActionInterface` - PATCH requests

Controllers can implement multiple interfaces if they handle multiple HTTP methods.

## Common Dependencies to Inject

Instead of `Context`, inject only what you need:

- `ResultFactory` - Create result objects (Page, Json, Redirect, Forward, Raw)
- `RequestInterface` - Access request parameters, POST data, headers
- `ResponseInterface` - Set response headers (CORS, cache control)
- `Registry` - Register data for blocks (deprecated pattern, but still used)
- `LayoutFactory` or `LayoutInterface` - Create blocks dynamically
- `JsonFactory` - Create JSON responses
- Specific services/helpers your controller needs

## Result Types

```php
// Page result (full page render)
$this->resultFactory->create(ResultFactory::TYPE_PAGE);

// JSON result (AJAX responses)
$resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
$resultJson->setData(['success' => true, 'data' => $data]);

// Redirect result
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('*/*/index');

// Forward result (internal forward to another controller)
$this->resultFactory->create(ResultFactory::TYPE_FORWARD);

// Raw result (plain text, CSV, etc.)
$this->resultFactory->create(ResultFactory::TYPE_RAW);
```

## Workflow

When invoked:

1. Ask user which scope to scan:
   - Specific directory (e.g., `app/code/Uptactics/`)
   - Specific module (e.g., `app/code/Uptactics/Rcc/`)
   - Single file

2. Search for deprecated patterns using Grep tool

3. Present findings with file paths and line numbers

4. For each file, offer to:
   - Show the current code
   - Explain what needs to change
   - Apply the refactoring automatically
   - Skip to next file

5. After refactoring, verify:
   - PHP syntax is valid
   - All dependencies are injected
   - Return type is correct

## Important Notes

- Always use `declare(strict_types=1);`
- Use PHP 8.3+ typed properties
- Never use `parent::execute()` after removing Action inheritance
- If controller uses `$this->_redirect()`, replace with ResultFactory redirect
- If controller uses `$this->messageManager`, inject it via constructor
- Preserve all existing business logic, only change the structure

## Safety Checks

Before refactoring:
- Confirm with user
- Show diff of changes
- Ensure no breaking changes to functionality
- Verify all injected dependencies are available

After refactoring:
- Check PHP syntax: `php -l <file>`
- Suggest running: `bin/magento setup:di:compile`
- Suggest clearing cache: `bin/magento cache:flush`

