CRUD básico inicial Codeigniter 4 - users

Este é um exemplo mínimo de como iniciar um #CRUD com #Codeigniter 4.
Vamos criar o Create, Update, Delete e Read de uma table users.

 

Primeiro instalamos o projeto. Instruções em: https://www.codeigniter.com/user_guide/installation/installing_composer.html

*Para este pequeno tutorial estamos considerando que seu ambiente de desenvolvimento já está configurado. Caso não esteja pesquise sobre como startar o PHP ou instale um servidor como WAMP, Apache ou Laragon ou, ainda, uma outra solução que te ajude nos testes.

composer create-project codeigniter4/appstarter project-root

Criamos o banco de dados e a table users

CREATE DATABASE `ci4-entity` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

-- `ci4-entity`.users definition

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `status` varchar(50) DEFAULT NULL,
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `deleted_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

app/Config/Routes.php

$routes->get('user', 'UserController::index');          // Listar todos os usuários
$routes->get('user/create', 'UserController::create');  // Formulário de criação de usuário
$routes->post('user/store', 'UserController::store');   // Salvar novo usuário
$routes->get('user/edit/(:num)', 'UserController::edit/$1'); // Formulário de edição de usuário
$routes->post('user/update/(:num)', 'UserController::update/$1'); // Atualizar usuário
$routes->get('user/delete/(:num)', 'UserController::delete/$1'); // Excluir usuário

app/Controllers/UserController.php

<?php
// app/Controllers/UserController.php
namespace App\Controllers;

use App\Models\UserModel;
use App\Entities\User;

class UserController extends BaseController
{
    public function index()
    {
        $userModel = new UserModel();

        // Configurando a paginação
        $data = [
            'users' => $userModel->paginate(10), // 10 usuários por página
            'pager' => $userModel->pager
        ];

        return view('user/index', $data);
    }

    public function create()
    {
        return view('user/create');
    }

    public function edit($id)
    {
        $userModel = new UserModel();
        $data['user'] = $userModel->find($id);
        return view('user/edit', $data);
    }

    public function update($id)
    {
        $userModel = new UserModel();
        $data = $this->request->getPost();

        // Verifica se a senha foi fornecida
        if (!empty($data['password'])) {
            $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        } else {
            // Se a senha não foi fornecida
            unset($data['password']);
        }

        // Atualiza os dados do usuário
        $userModel->update($id, $data);

        return redirect()->to('/user');
    }

    public function delete($id)
    {
        $userModel = new UserModel();
        $userModel->delete($id);
        return redirect()->to('/user')->with('message', 'Usuário excluído com sucesso');
    }

    public function store()
    {
        $userModel = new UserModel();

        $user = new User($this->request->getPost());
        $user->setPassword($this->request->getPost('password'));

        if ($userModel->save($user)) {
            return redirect()->to('/user/success');
        } else {
            var_dump($userModel->errors());
            die();
            // return redirect()->back()->withInput()->with('errors', $userModel->errors());
        }
    }
}

// app/Entities/User.php

<?php
// app/Entities/User.php
namespace App\Entities;

use CodeIgniter\Entity\Entity;

class User extends Entity
{
    protected $attributes = [
        'id'       => null,
        'name'     => null,
        'email'    => null,
        'password' => null,
        'status'   => null,
    ];

    protected $dates = ['created_at', 'updated_at'];

    // Método para setar a senha com hash
    public function setPassword(string $password)
    {
        $this->attributes['password'] = password_hash($password, PASSWORD_DEFAULT);
        return $this;
    }
}

// app/Models/UserModel.php

<?php
// app/Models/UserModel.php
namespace App\Models;

use CodeIgniter\Model;

class UserModel extends Model
{
    protected $table      = 'users';
    protected $primaryKey = 'id';
    protected $returnType = 'App\Entities\User';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['name', 'email', 'password', 'status'];
    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';
    protected $deletedField  = 'deleted_at';
}

app/Views/user/index.php

<!-- app/Views/user/index.php -->
<!DOCTYPE html>
<html>

<head>
    <title>Lista de Usuários</title>
</head>

<body>
    <h1>Lista de Usuários</h1>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Nome</th>
                <th>Email</th>
                <th>Status</th>
                <th>Ações</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($users as $user) : ?>
                <tr>
                    <td><?= esc($user->id) ?></td>
                    <td><?= esc($user->name) ?></td>
                    <td><?= esc($user->email) ?></td>
                    <td><?= esc($user->status) ?></td>
                    <td>
                        <a href="/user/edit/<?= $user->id ?>">Editar</a>
                        <a href="/user/delete/<?= $user->id ?>" onclick="return confirm('Tem certeza?')">Excluir</a>
                    </td>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>

    <!-- Links de Paginação -->
    <?= $pager->links() ?>
</body>

</html>

app/Views/user/edit.php

<!-- app/Views/user/edit.php -->
<!DOCTYPE html>
<html>

<head>
    <title>Editar Usuário</title>
</head>

<body>
    <h1>Editar Usuário</h1>
    <?php if (session()->getFlashdata('errors')) : ?>
        <div>
            <?php foreach (session()->getFlashdata('errors') as $error) : ?>
                <p><?= esc($error) ?></p>
            <?php endforeach ?>
        </div>
    <?php endif ?>
    <form action="<?= site_url(); ?>/user/update/<?= $user->id ?>" method="post">
        <?= csrf_field() ?>
        <label for="name">Nome:</label>
        <input type="text" name="name" id="name" value="<?= esc($user->name) ?>"><br>

        <label for="email">Email:</label>
        <input type="email" name="email" id="email" value="<?= esc($user->email) ?>"><br>

        <label for="password">Senha (deixe em branco para não alterar):</label>
        <input type="password" name="password" id="password"><br>

        <label for="status">Status:</label>
        <input type="text" name="status" id="status" value="<?= esc($user->status) ?>"><br>

        <button type="submit">Atualizar</button>
    </form>
</body>

</html>

app/Views/user/create.php

<!-- app/Views/user/create.php -->
<!DOCTYPE html>
<html>

<head>
    <title>Cadastro de Usuário</title>
</head>

<body>
    <h1>Cadastro de Usuário</h1>
    <?php if (session()->getFlashdata('errors')) : ?>
        <div>
            <?php foreach (session()->getFlashdata('errors') as $error) : ?>
                <p><?= esc($error) ?></p>
            <?php endforeach ?>
        </div>
    <?php endif ?>
    <form action="<?= site_url(); ?>/user/store" method="post">
        <?= csrf_field() ?>
        <label for="name">Nome:</label>
        <input required type="text" name="name" id="name" value="<?= old('name') ?>"><br>

        <label for="email">Email:</label>
        <input required type="email" name="email" id="email" value="<?= old('email') ?>"><br>

        <label for="password">Senha:</label>
        <input type="password" name="password" id="password"><br>

        <label for="status">Status:</label>
        <input required type="text" name="status" id="status" value="<?= old('status') ?>"><br>

        <button type="submit">Cadastrar</button>
    </form>
</body>

</html>

Este é apenas um simples exemplo de como é possível fazer um #CRUD com poucas linhas utilizando o #framework #Codeigniter 4 e #entity.
Ccompletar a solução vai além. É preciso processar os dados de entrada, tratá-los e validá-los. Também podemos adicionar o controle para verificar se o cadastro já existe e melhorar o feedback do usuário com alertas customizados como estes https://www.codesnippets.dev.br/post/ideias-para-alerts-com-informacoes-bootstrap-5