TableDataSource
Corex\Config\Data\TableDataSource · class · Config layer
A DataSource over a Corex-managed custom table (spec 038): it exposes the table’s declared columns and shapes each row to id + exactly those columns (extra columns dropped, missing ones defaulted to ”), so a managed table appears in Corex → Data like any other source with no new UI. The $wpdb access lives in the injected reader, so this shaping is unit-tested. Capabilities are derived from the table’s declaration rather than asserted here (spec 074), so a table that declares nothing stays read-only and cannot advertise an operation it never agreed to. Writes and migrations arrive through {@see WritableTableDataSource}, which is the subclass the registry builds when — and only when — the declaration asks for them.
Public API
Section titled “Public API”__construct(ManagedTable $table, TableDataReader $reader)
Section titled “__construct(ManagedTable $table, TableDataReader $reader)”ownerAbility(): ?string
Section titled “ownerAbility(): ?string”key(): string
Section titled “key(): string”category(): string
Section titled “category(): string”The group its table is in: the table’s two words are this interface’s two.
label(): string
Section titled “label(): string”columns(): array
Section titled “columns(): array”rows(int $page, int $perPage): array
Section titled “rows(int $page, int $perPage): array”The paged list. Shaped through {@see shapeRows()} like every other read path. It used to inline its own copy of the same loop, which is how it missed the attachment hydration query() and record() got: the Data screen’s list showed 21848 where its detail modal showed a link, from the same column on the same table. Two loops that must agree are one loop.
total(): int
Section titled “total(): int”delete(int $id): bool
Section titled “delete(int $id): bool”query(DataQuery $query): array
Section titled “query(DataQuery $query): array”count(DataQuery $query): int
Section titled “count(DataQuery $query): int”record(int $id): ?array
Section titled “record(int $id): ?array”exportRows(DataQuery $query): array
Section titled “exportRows(DataQuery $query): array”A managed table’s fields are its columns, so the row its table shows is the row an export writes.
exportRowsOf(array $ids): array
Section titled “exportRowsOf(array $ids): array”schema(): array
Section titled “schema(): array”The importable shape of this source. The type used to be hardcoded to text for every column, so a table that declared an attachment column described itself as holding text and every surface downstream rendered the id as a number (#138 item 6). It reads the declared type now, through the same allow-list fields() uses, so the two cannot disagree about what a column is.
capabilities(): DataSourceCapabilities
Section titled “capabilities(): DataSourceCapabilities”Everything this source can do, derived from the table’s declaration. Write, import, and migration flags come from the declaration and from the class being one that implements the matching interface. That makes the answer self-consistent by construction: a source can never report a capability the services would then refuse to honour, which was exactly the shape of the Import and Migrations dead ends this replaces.
fields(): array
Section titled “fields(): array”The field schema, with the declared writable fields marked writable and carrying the table’s own aliases and validation — which is what the import planner and validator read.