Hi Charlie,
I’ve found a bug in the Cornerstone Data Tables plugin when a table in AJAX mode is fed by a Query String Looper Provider. Every AJAX request (pagination, sort, search or length change) returns a 500 error, and the table gets stuck on “loading”.
Environment
- Pro theme with Cornerstone
- Cornerstone Data Tables (front-end script
cornerstone-datatable.js?ver=1.0.1) - Reproduced on PHP 8.1 and PHP 8.4
Steps to reproduce
- Create a Data Table with AJAX mode enabled.
- Give the table’s row looper a Query String provider, even a minimal one such as
post_type=post&posts_per_page=20. - On the front end, go to page 2, or scroll to trigger the next page.
Result
The request, for example ?cs_datatable_paged=2&cs_datatable_length=20&cs_datatable_fragment=... , returns a 500 with WordPress’s “There has been a critical error” page. The error is:
Uncaught TypeError: Cannot access offset of type string on string
in wp-content/plugins/cornerstone-datatable/extension/AjaxLooper.php:66
The stack trace shows the call coming from the cs_looper_provider_query_args filter callback registered at line 19 of AjaxLooper.php , applied in Cornerstone_Looper_Provider_User_Query->setup_query() .
Cause
For a Query String provider, cs_looper_provider_query_args receives $args as the raw query string , not an array. The callback in AjaxLooper.php assumes $args is always an array. Line 66 is simply the first write:
php
$args['posts_per_page'] = min( max( 1, intval( $_GET[ CS_DATATABLE_LENGTH_PARAM ] ) ), $max_length );
Page requests always include cs_datatable_length , so this line runs on every AJAX request. The same problem would occur at the orderby , order , s and offset assignments.
Suggested fix
Normalise $args at the top of the callback, before the early return check:
php
if ( is_string( $args ) ) {
$args = wp_parse_args( $args );
}
wp_parse_args() handles nested query-string syntax such as meta_query[clause][key]=... , so complex Query String providers survive the conversion intact, and WP_Query accepts the resulting array as normal.
Workaround in the meantime
This filter, running just before the plugin’s own callback, fixes the problem on my site:
php
add_filter( 'cs_looper_provider_query_args', function ( $args, $element = [] ) {
if ( ! is_string( $args ) ) {
return $args;
}
foreach ( array_keys( $_GET ) as $key ) {
if ( str_starts_with( $key, 'cs_datatable_' ) ) {
return wp_parse_args( $args );
}
}
return $args;
}, 19, 2 );
Related observations
-
Full-page crash: because the filter applies to every looper on the request, any page loaded with the
cs_datatable_parameters crashes, not just the fragment render. In my case, it happened when Rank Math calledget_the_excerpt()to build the Open Graph description, which rendered the Cornerstone content. - No retry limit: when the AJAX request fails, the front end retries the same request indefinitely, roughly every second or two. I saw dozens of identical 500s in a minute. A retry limit with back-off, and a visible error state in the table, would help both the user and the server.
-
Meta-key ordering: as the existing
@TODOnotes, meta-key ordering isn’t supported. A workaround that works well is a namedmeta_queryclause, for examplemeta_query[count_sort][key]=my_field&meta_query[count_sort][type]=NUMERIC, with the clause name (count_sort) as the header’s Order Column value. It might be worth mentioning in the docs until native support arrives.
Thanks,
Christopher