MagratheaPHP2
Up to date Narrative last written —; no source changes since. Method signatures below are reflected live.

MagratheaModelControl — Static ORM Query Interface

File: src/MagratheaModelControl.php Namespace: Magrathea2 Type: Abstract Class

The companion to MagratheaModel. Provides a static, repository-style interface for querying the database and returning typed model objects. You define one Control class per model.


Defining a Control

<?php
namespace App\Controls;

use Magrathea2\MagratheaModelControl;

class ProductControl extends MagratheaModelControl {
    protected static $modelName      = "Product";
    protected static $modelNamespace = "App\\Models";
    protected static $dbTable        = "products";
}

Required Static Properties

PropertyTypeExample
$modelNamestring"Product"
$modelNamespacestring"App\\Models"
$dbTablestring"products"

Static Query Methods

GetAll(): array<MagratheaModel>

Returns all records in the table, ordered by PK descending.

$products = ProductControl::GetAll();
foreach ($products as $product) {
    echo $product->name . "\n";
}

GetListPage(int $limit = 20, int $page = 0): array<MagratheaModel>

Paginated list of all records.

$page1 = ProductControl::GetListPage(20, 0); // first 20
$page2 = ProductControl::GetListPage(20, 1); // next 20

GetWhere(string|array $arr, string $condition = "AND"): array<MagratheaModel>

Fetch records matching a WHERE condition. Pass a raw SQL string or an associative array.

// Array form (recommended — safer)
$active = ProductControl::GetWhere(["active" => 1]);
$affordable = ProductControl::GetWhere(["active" => 1, "price <=" => "50.00"]);

// Raw SQL form
$recent = ProductControl::GetWhere("created_at > '2024-01-01'");

// OR condition
$either = ProductControl::GetWhere(["status" => "draft", "status" => "review"], "OR");

GetRowWhere(string|array $arr, string $condition = "AND"): object|array

Same as GetWhere but returns only the first matching record.

$product = ProductControl::GetRowWhere(["id" => 42]);
echo $product->name;

GetSimpleWhere(string $whereSql): array<MagratheaModel>

Fetch records with a raw WHERE SQL string (no table prefix, no WHERE keyword).

$results = ProductControl::GetSimpleWhere("price > 100 AND active = 1");

GetSelectArray(): array

Returns an associative array suitable for populating <select> dropdowns: [id => name].

$options = ProductControl::GetSelectArray();
// [1 => "Widget", 2 => "Gadget", ...]

Query Builder Integration

Run(Query $magQuery, bool $onlyFirst = false): array<MagratheaModel>

Execute a Query object and return typed model instances.

use Magrathea2\DB\Query;

$query = Query::Select()
    ->Obj(new Product())
    ->Where(["active" => 1])
    ->Order("price ASC")
    ->Limit(10);

$products = ProductControl::Run($query);

RunMagQuery(Query $magQuery): array<MagratheaModel>

Alias for Run.

Count(Query $magQuery): int

Execute a COUNT query for the given query builder.

$query = Query::Select()->Obj(new Product())->Where(["active" => 1]);
$total = ProductControl::Count($query);
echo "Total active products: $total";

RunPagination(Query $magQuery, &$total, int $page = 0, int $limit = 20, bool $withTotal = true): array<MagratheaModel>

Executes a query with pagination, also returning the total count by reference. Pass $withTotal = false to skip the COUNT(*) query — $total is then left as null.

$query = Query::Select()->Obj(new Product())->Where(["active" => 1]);

$total = 0;
$products = ProductControl::RunPagination($query, $total, page: 0, limit: 20);

echo "Showing " . count($products) . " of $total";

GetPagination(Query $magQuery, int $page = 0, int $limit = 20, bool $withTotal = false): MagratheaPagination

Builds a MagratheaPagination object directly from a query — the recommended way to paginate an API endpoint. Return it straight from an API controller action and MagratheaApi::ReturnSuccess() will build the paginated JSON envelope ({success, data, page, count, has_more, total?}) automatically.

By default ($withTotal = false) it avoids an extra COUNT() query: it fetches $limit + 1 rows, and if that extra row comes back, sets has_more = true and trims the result back down to $limit. Pass $withTotal = true to also compute and include total (at the cost of a COUNT() query).

use Magrathea2\DB\Query;
use App\Controls\ProductControl;

// In an API controller:
public function List(array $params = []): \Magrathea2\MagratheaPagination {
    $query = Query::Select()->Obj(new \App\Models\Product())->Where(["active" => 1])->Order("name ASC");
    return ProductControl::GetPagination($query, page: (int)($params["page"] ?? 0), limit: 20);
}
{"success": true, "data": [ ... ], "page": 0, "count": 20, "has_more": true}

Raw SQL Methods

RunQuery(string $sql): array<MagratheaModel>

Execute a raw SQL SELECT and map results to model objects.

$products = ProductControl::RunQuery(
    "SELECT * FROM products WHERE category_id IN (1,2,3) ORDER BY name"
);

RunRow(string $sql): object|null

Execute raw SQL and return only the first result as a model object.

$product = ProductControl::RunRow("SELECT * FROM products WHERE sku = 'WIDGET-001'");

QueryResult(string $sql): array

Execute raw SQL and return raw result rows (not mapped to models).

QueryRow(string $sql): array

Execute raw SQL and return the first row as an array.

QueryOne(string $sql): mixed

Execute raw SQL and return the first column of the first row.

$maxPrice = ProductControl::QueryOne("SELECT MAX(price) FROM products");

Multi-Object Joins

GetMultipleObjects(array $array_objects, string $joinGlue, string $where = ""): array

Build a multi-table query using multiple models and return combined results.

$results = ProductControl::GetMultipleObjects(
    [new Product(), new Category()],
    "products.category_id = categories.id",
    "products.active = 1"
);

Utility

GetModelName(): string

Returns the model class name.

ShowAll(): void

Dumps all records to output (debug helper).


Full Example: Paginated Product List

use Magrathea2\DB\Query;
use App\Controls\ProductControl;

// Build query
$query = Query::Select()
    ->Obj(new \App\Models\Product())
    ->Where(["active" => 1])
    ->Order("name ASC");

// Get page 2, 15 items per page
$total    = 0;
$products = ProductControl::RunPagination($query, $total, page: 1, limit: 15);

// Output
echo json_encode([
    "total"    => $total,
    "page"     => 1,
    "per_page" => 15,
    "data"     => array_map(fn($p) => $p->ToJson(), $products),
]);

Full Example: Search & Filter

use Magrathea2\DB\Query;
use App\Controls\ProductControl;

$search = Query::Clean($_GET["q"] ?? "");
$minPrice = (float)($_GET["min"] ?? 0);

$query = Query::Select()
    ->Obj(new \App\Models\Product())
    ->Where(["active" => 1]);

if ($search) {
    $query->Where("name LIKE '%$search%'");
}

if ($minPrice > 0) {
    $query->Where("price >= $minPrice");
}

$query->Order("name ASC")->Limit(20);

$results = ProductControl::Run($query);

Notes

Class Reference — MagratheaModelControl

Magrathea2\MagratheaModelControl implements Stringable abstract /home/platypusweb/platypusweb.com.br/site/magratheaphp2/src/MagratheaModelControl.php
static Count(Magrathea2\DB\Query $magQuery): int

Runs a Magrathea Query and returns the count of matching rows

ParamTypeDefault
$magQuery Magrathea2\DB\Query required
static GetAll()

Gets all from this object

static GetListPage(int $limit = 20, int $page = 0)

Gets all from this object

ParamTypeDefault
$limit int 20
$page int 0
static GetModelName()
static GetMultipleObjects($array_objects, $joinGlue, $where = "")

This function allows to build a query getting multiple objects at once

ParamTypeDefault
$array_objects mixed required
$joinGlue mixed required
$where mixed ""
static GetPagination(Magrathea2\DB\Query $magQuery, $page = 0, $limit = 20, $withTotal = false)

Runs query with Pagination and returns a MagratheaPagination object, ready to be returned directly from an API controller (MagratheaApi::ReturnSuccess() recognizes it). By default ($withTotal=false), avoids the extra COUNT(*) query: it fetches one row more than requested to determine `has_more`, then trims the result back to $limit.

ParamTypeDefault
$magQuery Magrathea2\DB\Query required
$page mixed 0
$limit mixed 20
$withTotal mixed false
static GetRowWhere(array|string $arr, $condition = "AND")

Builds query with where clause, returning only first row

ParamTypeDefault
$arr array|string required
$condition mixed "AND"
static GetSelectArray()

Gets all from this object

static GetSimpleWhere(string $whereSql)

Builds query with where clause

ParamTypeDefault
$whereSql string required
static GetWhere(array|string $arr, $condition = "AND")

Builds query with where clause

ParamTypeDefault
$arr array|string required
$condition mixed "AND"
static QueryOne(string $sql)

Runs a query and returns the first result

ParamTypeDefault
$sql string required
static QueryResult(string $sql)

Runs a query and returns the result

ParamTypeDefault
$sql string required
static QueryRow(string $sql)

Runs a query and returns the first row of result

ParamTypeDefault
$sql string required
static Run(Magrathea2\DB\Query $magQuery, $onlyFirst = false)

Runs a Magrathea Query and returns a list of objects

ParamTypeDefault
$magQuery Magrathea2\DB\Query required
$onlyFirst mixed false
static RunMagQuery(Magrathea2\DB\Query $magQuery)

Runs a Magrathea Query and returns a list of objects (calls Run function)

ParamTypeDefault
$magQuery Magrathea2\DB\Query required
static RunPagination(Magrathea2\DB\Query $magQuery, $total, $page = 0, $limit = 20, $withTotal = true)

Runs query with Pagination. This way, is not necessary to worry about including pagination on Magrathea Query, this function can deal with it

ParamTypeDefault
$magQuery Magrathea2\DB\Query required
$total mixed required
$page mixed 0
$limit mixed 20
$withTotal mixed true
static RunQuery(string $sql)

Run a query and return a list of the objects

ParamTypeDefault
$sql string required
static RunRow(string $sql)

Run a query and return the first object available

ParamTypeDefault
$sql string required
static ShowAll()

Show all elements from an object

Examples