Skip to content

Models and Validation

Lukman Nakib edited this page May 30, 2026 · 1 revision

Models & Validation

Models extend Model\BaseModel — a thin wpdb ORM. Validation lives on the Model, not in controllers.

final class Book extends BaseModel
{
    protected static $table = 'wppm_books';                       // resolved as $wpdb->prefix . $table

    protected static array $fillable = ['title', 'author', 'status'];
    protected static array $sortable = ['id', 'title', 'author', 'status']; // ORDER BY / filter / search whitelist
    protected static array $rules    = [
        'title'  => ['required', 'string', 'max:191'],
        'status' => ['in:draft,published'],
    ];
}

CRUD

Book::all();
Book::find(1);
Book::create(['title' => 'Dune']);              // applies $fillable
(new Book())->where('status', 'draft')->get();
$book->update(['status' => 'published']);
$book->delete();

// Pagination powers ListPage:
Book::paginate($page = 1, $perPage = 20, [
    'sort' => 'title', 'direction' => 'asc',
    'filters' => ['status' => 'published'],
    'search' => 'dune', 'searchable' => ['title'],
]); // → ['data' => Book[], 'total' => int, 'page' => int, 'per_page' => int]

The controller pattern

Controllers stay thin — fill → validate → save → respond:

public function update($request)
{
    $book = Book::find($request['id']);
    $errors = $book->fill($request)->validate();
    if ($errors) {
        return wp_send_json_error(['errors' => $errors], 422);
    }
    $book->save();
    wp_send_json_success($book);
}

Rules grammar

A rule is a string (required, string, max:191, in:a,b,c) or a closure fn($value, $field, $attributes): true|string. validate() returns field => string[] (empty = valid). The ListPage edit form is generated from these rules.

Guards

  • $fillable — mass-assignment whitelist for fill()/create(). Empty = allow all (legacy).
  • $sortable — the only columns paginate() will sort/filter/LIKE-search; everything else is ignored. This is the SQL-injection guard — keep it tight.

Generate one with wp matrix:make:model Book (and wp matrix:make:migration create_books_table).

Clone this wiki locally