Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    victorsmaniotto

    legacy-modernizer

    victorsmaniotto/legacy-modernizer
    Coding
    1 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Modernização de código PHP legado para padrões atuais (PHP 7.4-8.3)...

    SKILL.md

    Legacy Modernizer

    Skill para transformação de código PHP legado em código moderno e maintainable.

    Checklist de Modernização

    1. Sintaxe PHP 8.x - Type hints, named arguments, match, enums
    2. OOP - Classes, interfaces, traits, composition
    3. SOLID - Single responsibility, dependency injection
    4. PSR - Autoload, coding style, interfaces
    5. Error Handling - Exceptions em vez de error codes
    6. Testing - Código testável e desacoplado

    Transformações Comuns

    1. Sintaxe Moderna

    // ❌ ANTES: PHP 5.x
    function getUser($id) {
        global $db;
        $result = mysql_query("SELECT * FROM users WHERE id = " . $id);
        if ($result) {
            return mysql_fetch_assoc($result);
        }
        return false;
    }
    
    // ✅ DEPOIS: PHP 8.x
    function getUser(int $id): ?array
    {
        return DB::table('users')->find($id)?->toArray();
    }
    

    2. Type Declarations

    // ❌ ANTES
    function calcularTotal($items, $desconto) {
        $total = 0;
        foreach ($items as $item) {
            $total += $item['valor'];
        }
        return $total - $desconto;
    }
    
    // ✅ DEPOIS
    function calcularTotal(array $items, float $desconto = 0): float
    {
        $total = array_sum(array_column($items, 'valor'));
        return max(0, $total - $desconto);
    }
    
    // ✅ MELHOR: Com objetos
    function calcularTotal(Collection $items, float $desconto = 0): float
    {
        return max(0, $items->sum('valor') - $desconto);
    }
    

    3. Procedural para OOP

    // ❌ ANTES: Funções soltas
    function criar_contrato($dados) { ... }
    function atualizar_contrato($id, $dados) { ... }
    function buscar_contrato($id) { ... }
    function listar_contratos($filtros) { ... }
    
    // ✅ DEPOIS: Service Class
    class ContractService
    {
        public function __construct(
            private ContractRepository $repository,
            private EventDispatcher $events
        ) {}
    
        public function create(array $data): Contract
        {
            $contract = $this->repository->create($data);
            $this->events->dispatch(new ContractCreated($contract));
            return $contract;
        }
    
        public function update(int $id, array $data): Contract
        {
            $contract = $this->repository->findOrFail($id);
            $contract->update($data);
            return $contract;
        }
    
        public function find(int $id): ?Contract
        {
            return $this->repository->find($id);
        }
    
        public function list(array $filters = []): Collection
        {
            return $this->repository->filter($filters);
        }
    }
    

    4. Global State para DI

    // ❌ ANTES: Globals
    function enviarEmail($para, $assunto, $corpo) {
        global $config;
        $mail = new PHPMailer();
        $mail->Host = $config['smtp_host'];
        // ...
    }
    
    // ✅ DEPOIS: Dependency Injection
    class EmailService
    {
        public function __construct(
            private readonly MailerInterface $mailer,
            private readonly MailConfig $config
        ) {}
    
        public function send(string $to, string $subject, string $body): void
        {
            $this->mailer
                ->to($to)
                ->subject($subject)
                ->body($body)
                ->send();
        }
    }
    

    5. Arrays para Value Objects

    // ❌ ANTES: Array associativo
    $contrato = [
        'cliente' => 'João',
        'valor' => 1500.00,
        'data' => '2024-01-15',
        'status' => 'ativo'
    ];
    
    // ✅ DEPOIS: DTO/Value Object
    readonly class Contract
    {
        public function __construct(
            public string $cliente,
            public float $valor,
            public DateTimeImmutable $data,
            public ContractStatus $status
        ) {}
    
        public static function fromArray(array $data): self
        {
            return new self(
                cliente: $data['cliente'],
                valor: (float) $data['valor'],
                data: new DateTimeImmutable($data['data']),
                status: ContractStatus::from($data['status'])
            );
        }
    }
    
    enum ContractStatus: string
    {
        case Ativo = 'ativo';
        case Cancelado = 'cancelado';
        case Finalizado = 'finalizado';
    
        public function label(): string
        {
            return match($this) {
                self::Ativo => 'Ativo',
                self::Cancelado => 'Cancelado',
                self::Finalizado => 'Finalizado',
            };
        }
    }
    

    6. Callbacks para Arrow Functions

    // ❌ ANTES: Callback verbose
    $ativos = array_filter($contratos, function($c) {
        return $c['status'] == 'ativo';
    });
    
    $valores = array_map(function($c) {
        return $c['valor'];
    }, $ativos);
    
    $total = array_reduce($valores, function($carry, $v) {
        return $carry + $v;
    }, 0);
    
    // ✅ DEPOIS: Arrow functions + Collection
    $total = collect($contratos)
        ->filter(fn($c) => $c['status'] === 'ativo')
        ->sum('valor');
    

    7. Switch para Match

    // ❌ ANTES
    switch ($status) {
        case 'pending':
            $label = 'Pendente';
            $color = 'yellow';
            break;
        case 'active':
            $label = 'Ativo';
            $color = 'green';
            break;
        case 'cancelled':
            $label = 'Cancelado';
            $color = 'red';
            break;
        default:
            $label = 'Desconhecido';
            $color = 'gray';
    }
    
    // ✅ DEPOIS
    [$label, $color] = match($status) {
        'pending' => ['Pendente', 'yellow'],
        'active' => ['Ativo', 'green'],
        'cancelled' => ['Cancelado', 'red'],
        default => ['Desconhecido', 'gray'],
    };
    

    8. Error Handling

    // ❌ ANTES: Error codes
    function processarPagamento($dados) {
        if (!isset($dados['valor'])) {
            return ['erro' => true, 'mensagem' => 'Valor obrigatório'];
        }
        if ($dados['valor'] <= 0) {
            return ['erro' => true, 'mensagem' => 'Valor inválido'];
        }
        // processar...
        return ['erro' => false, 'id' => 123];
    }
    
    // ✅ DEPOIS: Exceptions
    class PaymentService
    {
        public function process(PaymentData $data): Payment
        {
            $this->validate($data);
            
            try {
                return $this->gateway->charge($data);
            } catch (GatewayException $e) {
                throw new PaymentFailedException(
                    "Falha no pagamento: {$e->getMessage()}",
                    previous: $e
                );
            }
        }
    
        private function validate(PaymentData $data): void
        {
            if ($data->valor <= 0) {
                throw new InvalidArgumentException('Valor deve ser positivo');
            }
        }
    }
    

    Padrão de Migração Incremental

    1. Criar interfaces para código existente
    2. Implementar nova versão atrás da interface
    3. Usar feature flags para alternar
    4. Remover código antigo após validação
    
    // Interface de abstração
    interface ContractRepositoryInterface
    {
        public function find(int $id): ?Contract;
        public function save(Contract $contract): void;
    }
    
    // Implementação legada (wrapper)
    class LegacyContractRepository implements ContractRepositoryInterface
    {
        public function find(int $id): ?Contract
        {
            $data = buscar_contrato($id); // função legada
            return $data ? Contract::fromArray($data) : null;
        }
    }
    
    // Nova implementação
    class EloquentContractRepository implements ContractRepositoryInterface
    {
        public function find(int $id): ?Contract
        {
            return ContractModel::find($id)?->toDomain();
        }
    }
    
    // Service Provider com feature flag
    $this->app->bind(
        ContractRepositoryInterface::class,
        config('features.new_repository') 
            ? EloquentContractRepository::class 
            : LegacyContractRepository::class
    );
    

    Scripts Úteis

    • scripts/analyze-legacy.php - Análise de código legado
    • scripts/convert-array-to-dto.php - Converter arrays em DTOs
    Recommended Servers
    Svelte
    Svelte
    Context7
    Context7
    Prisma
    Prisma
    Repository
    victorsmaniotto/degestao
    Files