Data Tables - Bug In Ajaxlooper.php

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

  1. Create a Data Table with AJAX mode enabled.
  2. Give the table’s row looper a Query String provider, even a minimal one such as post_type=post&posts_per_page=20 .
  3. 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 called get_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 @TODO notes, meta-key ordering isn’t supported. A workaround that works well is a named meta_query clause, for example meta_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