/

Informes SQL personalizados

Respalda una cuadrícula con una sentencia SELECT de solo lectura arbitraria mediante query(), para informes que no se corresponden con una única tabla.

table() frente a query()

->table($name) respalda una cuadrícula con una tabla real y editable. ->query($sql) es la alternativa para cualquier cosa que no se corresponda con una única tabla - uniones (joins), agregados, columnas calculadas que abarcan varias tablas:

public function query(string $sql): self

$sql se usa literalmente, envuelta como una tabla derivada por la capa de la API - exactamente el mismo nivel de confianza que tienen las propias vías de escape de SQL sin procesar de where_raw()/subselect(). Debe ser una cadena simple que hayas escrito tú mismo en el PHP de tu propia página, nunca algo construido a partir de la entrada de la petición.

El modo informe es de solo lectura

Una cuadrícula en modo query no tiene Añadir/Editar/Eliminar, ni acciones masivas, ni edición en línea - es de solo lectura por naturaleza, ya que no hay una única tabla a la que una escritura pudiera dirigirse sin ambigüedad. Esto se aplica tanto del lado del cliente como del servidor: la API rechaza directamente POST/PUT/DELETE contra una ruta en modo query, sin importar lo que envíe el cliente. Solo quedan listar/buscar/ordenar/paginar/exportar.

columns() y route() siguen siendo obligatorios

Una cuadrícula en modo query nunca abre una conexión de base de datos propia para descubrir columnas - su lista de columnas es únicamente lo que diga ->columns(). ->route() es igualmente obligatorio, ya que no hay ningún nombre de tabla del que derivar uno por defecto.

Un ejemplo basado en JOIN

$xcrud = Xcrud::get_instance();
$xcrud->route('order-summary');
$xcrud->query(
    'SELECT o.orderNumber, o.orderDate, o.status, c.customerName, c.country,
            COUNT(od.id) AS itemCount,
            SUM(od.quantityOrdered * od.priceEach) AS orderTotal
     FROM orders o
     JOIN customers c ON c.customerNumber = o.customerNumber
     JOIN orderdetails od ON od.orderNumber = o.orderNumber
     GROUP BY o.orderNumber, o.orderDate, o.status, c.customerName, c.country'
);
$xcrud->columns('orderNumber,orderDate,status,customerName,country,itemCount,orderTotal');
$xcrud->order_by('orderTotal', 'desc');
$xcrud->title('Order Summary Report');

echo $xcrud->render();

Los propios alias de columna de $sql y los nombres de ->columns() nunca se cotejan entre sí (no hay acceso a la base de datos en el momento de renderizar) - un desajuste aparece como un error en la primera petición real de la cuadrícula, no como una excepción en tiempo de renderizado como ocurriría con un nombre de columna desconocido en order_by()/label()/where(). Comprueba las dos listas a mano.

Un ORDER BY final dentro de $sql sin LIMIT puede descartarse silenciosamente una vez envuelto como tabla derivada - inofensivo, ya que el propio orden/->order_by() de la cuadrícula siempre aplica un ORDER BY externo de todos modos, pero no confíes en que uno interno haga nada por sí solo.