Modifying the entries displayed in a View
Warning: this page is for developers. If you only need to filter which entries a View shows, the Advanced Filter extension does it without code.
GravityView gives you three hooks for changing which entries a View shows, and each acts at a different stage of the query. Use the earliest one that can express your logic: the earlier the hook, the more GravityView can keep the entry count and pagination correct for you.
Which hook to use #
| Hook | Stage | Best for |
|---|---|---|
gk/gravityview/search/request/search-arguments | Before the query is built | Conditions on a field value. Counts and pagination stay correct on their own. |
gravityview/view/query | Before the query runs | Anything that needs SQL: joins, IN lists, comparisons between columns. |
gravityview/view/entries | After the entries are fetched | Logic that cannot be expressed in SQL. You become responsible for the count and pagination. |
Adding a condition before the query #
gk/gravityview/search/request/search-arguments is a filter over the search request GravityView builds from the URL. Add an entry to the array and it becomes part of the query, whether or not the visitor searched for anything.
add_filter(
'gk/gravityview/search/request/search-arguments',
function ( $arguments, $request, $view ) {
if ( ! $view || 123 !== $view->ID ) {
return $arguments;
}
// Keys are request keys, not field IDs:
// filter_<id>, gv_search, gv_start, gv_end, gv_by, gv_id.
$arguments['filter_5'] = [
'value' => get_current_user_id(),
'operator' => 'is',
];
return $arguments;
},
10,
3
);Three things to know about this filter:
- The array is keyed by the request key, not the field ID. A search on field 5 arrives as
filter_5, and each value is an array ofvalueandoperator. - It runs more than once per request, and on one of those runs
$viewisnull. Check it before using it, as the example does. - Return an array. Returning
nullor a string discards the whole search silently, and the View shows every entry.
Changing the SQL query #
gravityview/view/query is an action, not a filter. It hands you the GF_Query object by reference, so you modify it in place and return nothing. Reach for it when the condition cannot be written as a field filter.
add_action( 'gravityview/view/query', function ( &$query, $view, $request ) {
if ( ! $view || 123 !== $view->ID ) {
return;
}
$condition = new GF_Query_Condition(
new GF_Query_Column( 5, $view->form->ID ),
GF_Query_Condition::EQ,
new GF_Query_Literal( 'active' )
);
// Keep the conditions GravityView already built, and add yours.
$where = $query->_introspect()['where'];
$query->where( GF_Query_Condition::_and( $where, $condition ) );
}, 10, 3 );Warning: keep $query->_introspect()['where'] in the condition. Calling $query->where() with only your own condition throws away the View’s own filtering, including Advanced Filter rules and approval status.
Filtering entries after they are fetched #
gravityview/view/entries receives a \GV\Entry_Collection. Entries cannot be removed from a collection, so build a new one and return that.
add_filter( 'gravityview/view/entries', function ( $entries, $view, $request ) {
if ( ! $view || 123 !== $view->ID ) {
return $entries;
}
$keep = new \GV\Entry_Collection();
foreach ( $entries->all() as $entry ) {
// Add only the entries you want to keep.
$keep->add( $entry );
}
return $keep;
}, 10, 3 );The count and pagination are built from the query, not from what you return here, so removing entries at this stage leaves the entry count and the page links reporting the original number. That is the reason to prefer one of the earlier hooks when you can.
Read here how to add these code samples to your website: Where to put code samples.
If you are using gravityview_fe_search_criteria #
gravityview_fe_search_criteria was the old way to add conditions before the query, and it was deprecated in 2.55. It still runs, so existing code keeps working, but it prints a deprecation notice in the dashboard when WP_DEBUG is on.
The dashboard notice points at gravityview/view/query. That is the right answer when you need SQL, but for the usual case of adding a field condition, gk/gravityview/search/request/search-arguments is the closer equivalent and the easier migration: both are filters that take an array of conditions and return it. The old callback received an array of field_filters with key, value and operator; the new one receives an array keyed by request key, with value and operator inside.
Translating your old callback
Both hooks hand you the conditions before the query runs, so most callbacks translate directly. What changes is the shape of the array. The old filter gave you a numbered list under field_filters, each entry carrying its own key. The new one gives you an array keyed by the request key, with only the value and the operator inside. These are the keys to expect:
| What the visitor searched on | Key in the array | Field the condition ends up on |
|---|---|---|
| Field 5 | filter_5 | 5 |
| Input 3 of a multi-part field 5 | input_5_3 | 5.3 |
| The Search Everything box | gv_search | search_all |
| Entry date range | gv_start and gv_end | entry_date |
| Entry creator | gv_by | created_by |
| Entry ID | gv_id | entry_id |
So a callback that appended a condition:
// Old.
$criteria['field_filters'][] = [
'key' => '5',
'value' => 'active',
'operator' => 'is',
];
// New.
$arguments['filter_5'] = [
'value' => 'active',
'operator' => 'is',
];Because the new array is keyed, removing one of the visitor’s own search conditions is a single unset() rather than a loop:
add_filter(
'gk/gravityview/search/request/search-arguments',
function ( $arguments, $request, $view ) {
// Ignore whatever the visitor typed into the field 3 search box.
unset( $arguments['filter_3'] );
return $arguments;
},
10,
3
);Warning: changing the operator on a condition the visitor submitted is not reliable here. The value you set survives this filter, but the operator a field will accept is decided separately by gk/gravityview/search/operators/allowed, and a text field allows only =. If you need a different comparison, do it with gravityview/view/query above, where you build the condition yourself.
See Deprecated and renamed hooks for every GravityView hook that has been renamed, and the GravityKit developer docs for the full signature of each hook on this page.