setCustomQuery
setCustomQuery(string $selectQuery[, string $countQuery])
Set a custom select query for datagrid data retrieval. You can use setCustomQuery to provide your own SQL query
for the listing/datagrid operation. This is useful when you need to have complex queries that involve joins,
subqueries, or specific filtering.
⚠️ There are some limitations when using
setCustomQuery:
- Currently, we are not supporting filtering and sorting. We may add support for these features in future releases.
- Pagination is only supported when you provide the second parameter
$countQuery.- You always need to return the primary key of the table in the select query for proper functioning of the CRUD operations.
- The filtering on the custom query will not filter the results of the CRUD operations (edit, delete, etc). In case you need to filter the results of the CRUD operations you will either need to use
$crud->where()or have custom validation on "before" callbacks for all the operations.
Pagination is only supported when you provide the second parameter $countQuery. If you do not provide it then all
the data will be fetched in the datagrid without pagination.
Example Usage
$selectQuery = "SELECT users.id, users.name, roles.role_name
FROM users
JOIN roles ON users.role_id = roles.id
WHERE users.active = 1";
$countQuery = "SELECT COUNT(*) as num
FROM users
JOIN roles ON users.role_id = roles.id
WHERE users.active = 1";
$crud->setCustomQuery($selectQuery, $countQuery);
or without pagination:
$selectQuery = "SELECT users.id, users.name, roles.role_name
FROM users
JOIN roles ON users.role_id = roles.id
WHERE users.active = 1 AND roles.role_name = 'Manager'";
$crud->setCustomQuery($selectQuery);
$crud->unsetPagination();
Full Example
You can find a full working example below:
$selectQuery = "
SELECT
f.film_id,
f.title,
f.release_year,
GROUP_CONCAT(a.fullname SEPARATOR ', ') AS actors
FROM film f
JOIN film_actor fa ON f.film_id = fa.film_id
JOIN actor a ON fa.actor_id = a.actor_id
WHERE f.rating = 'PG'
GROUP BY f.film_id, f.title, f.release_year
";
$countQuery = "
SELECT COUNT(DISTINCT f.film_id) AS num
FROM film f
JOIN film_actor fa ON f.film_id = fa.film_id
JOIN actor a ON fa.actor_id = a.actor_id
WHERE f.rating = 'PG'
";
$crud->setCustomQuery($selectQuery, $countQuery);
$crud->setSubject('Film', 'PG Rating Films');
$crud->columns(['title', 'release_year', 'actors']);
$crud->setTable('film'); // Table name is still required for CRUD operations
// Some additional configurations which will make more sense for this example
$crud->unsetAdd();
$crud->readOnlyEditFields(['rating']);
// Using where to filter CRUD operations so users with no access to not be able to
// edit/delete films that are not 'PG'
$crud->where(['rating' => 'PG']);
$crud->setRelationNtoN(
'actors', 'film_actor',
'actor', 'film_id',
'actor_id', 'fullname',
null, null, 'priority'
);
$crud->setRelationNtoN(
'categories', 'film_category',
'category', 'film_id',
'category_id', 'name',
null, null, 'priority'
);
// Last changes, since we are using a custom query, we need to disable filtering and ordering
// and do some changes on the default field types for columns:
$crud->fieldTypeColumn('title', 'varchar');
$crud->fieldTypeColumn('release_year', 'varchar');
$crud->fieldTypeColumn('actors', 'varchar');
$crud->unsetFilters();
$crud->unsetSearchColumns(['title', 'release_year', 'actors']);
$crud->unsetSortingColumns(['title', 'release_year', 'actors']);
$crud->unsetDeleteMultiple();
$output = $crud->render();
You can see the results for the above example at the below demo: