ajax request result versus widget result & foreach error

This topic is: not resolved
Viewing 9 posts - 1 through 9 (of 9 total)
Author Posts
November 7, 2014 at 9:16 am #3561
Post count: 13

hi again,

i’ve been converting some of the data code in my template into function within the functions.php file.

I’ve found that when I use ajax to request the data, I get a for loop error:
Warning: Invalid argument supplied for foreach()…. /wp-content/plugins/masterpress/core/api/woof/woof.php on line 1832

When I load the page initially using the short code, it loads fine.

In the template I have the following code:
<?php echo do_shortcode( ‘[testfield]’ ) ?>

My ajax call, calls my_action_callback() below, which should return the flight data.

In my functions.php file I have:
add_action( ‘wp_ajax_nopriv_my_action’, ‘my_action_callback’ );
add_shortcode(‘testfield’, ‘flight_table’);

function my_action_callback() {
global $wpdb; // this is how you get access to the database

// Get and sanitise variables
$var1 = (string) $_POST[‘var1’];

// Clear existing filters
$filter = array();

$filter = array(
“value” => “key”,

echo returnTable();
die(); // this is required to terminate immediately and return a proper response

which then calls:

function returnTable() {
global $wf;
$query = $wf->the->custom-post-type;

$string = “”;
foreach ($wf->loop() as $post) {

$fieldset = $post->custom-post-type;
$var1 = $fieldset->var1;
$string .= $var1;

return $string;

I initially had the ajax calls working, but not the other way around. This seemed to work when I replaced the Masterpress for loop with the standard call, and a global $post variable and query in the returnTable() function:

$args = array(
‘post_type’ => ‘custom-post-type’,
$custom-post-type_posts = new WP_Query($args);
while ( $custom-post-type_posts->have_posts() ) : $custom-post-type_posts->the_post();

November 7, 2014 at 10:28 am #3562
Post count: 207

Hey there. Yeah, I suspect this doesn’t work because there’s no notion of the “current post” or the current query when using the AJAX filters, so the call to $wf->the, or $wf->loop fails. I suspect you’d have to pass the post ID you’re looking for. $wf->loop will only work when you’ve got a global query object representing the current query for an archive page. If you’re trying to loop over the posts for a specific custom post type, you’d need to use:

foreach ($wf->type(“custom_post_type”)->posts as $post)

which should still work in an AJAX handler, as it doesn’t reply on global state. You can also shorten this and use:

foreach ($wf->custom_post_types as $post)

which will look for a post type based on the singular form of “custom_post_types”. That actually returns a WOOF_PostType object, not a collection, but WOOF_PostType implements the Iterator interface, and will return a collection of posts in that type when used in conjunction with foreach.

November 7, 2014 at 11:08 am #3563
Post count: 13


Yes thought that may be the case.

The way I’m using the data is a collection of objects (archive page), rather than individual posts . This is true at all times, so I won’t have a specific post ID… I think that is where I’ve been running into a few issues..

I’ll try explicitly setting the post query to retrieve the full list of posts…

November 7, 2014 at 11:38 am #3564
Post count: 13

Changing the loop code works.

Is there a master press friendly way to set the $wf variable similar to:
$args = array(
‘post_type’ => ‘custom_post_type’,
‘post_status’ => ‘published’

$flight_posts = new WP_Query($args);

November 7, 2014 at 11:48 am #3565
Post count: 13

I think I may have solved by own question with a big of debugging:
$posts = $wf->type(‘custom_post_type’)->posts();

foreach ($posts as $post) {
$set = $post->custom_field_set;

Then I can use the values.

November 7, 2014 at 11:58 am #3566
Post count: 13

OK, one last problem hopefully related to this. With my query set to get a list of posts, and not the collection of fields.. the filter doesn’t work.. says method doesn’t exist.

$query = $wf->the->custom_data_type->filter($filter_query_masterpress);

So in order to set the initial query with a collection of the datatype, what query would I use?

Currently I’m using $posts = $wf->type(‘custom_data_type’)->posts();
which returns the post objects and not the collection to filter on.

I think once that is solved, the function should work with Ajax and initial load, because the context of post will always be set to retrieve the entire collection of objects.

November 7, 2014 at 4:48 pm #3567
Post count: 13

OK, seems I’ve solved it. The following outputs the filtered field set..

foreach ($wf->loop() as $the) {

foreach ($the->field_type->filter(“hair=brown&eyes=blue”) as $person) {


I’m noticing though it doesn’t filter based on both matches.. It will include any result where one of the filters matches. Is this expected, or is there a work around to filter combined?

November 8, 2014 at 3:30 pm #3568
Post count: 13

ok, i’ve gone through the filter code and it will include any match.. I’ve reversed the loop so that it will do an ‘and’ match (1 or more must be true to be added). Any chance this could be added in a future release as a variable to the function? i.e. Exclusive filter

function filterExclusive($args, $case_sensitive = FALSE) {
$filters = array();
$filtered_items = array();

if (!is_array($args)) {
$args = explode(“&”, $args);

// extract the arguments

foreach ($this->_items as $set_item) {
$include = true;

foreach ($args as $arg) {

$m = array();

preg_match ( “/^([\w\-]+)(\#?\=|\#?[\>\<\$\^\*\~\!]=|\#?\>|\#?\<)(.*)$/” , $arg, $m );

if ($m && count($m) == 4) {
$fn = $m[1];
$op = $m[2];

if ($case_sensitive) {
$val = $m[3];
} else {
$val = strtolower($m[3]);

$f = $set_item->f($fn);

$fields = array();

$fields[] = $f;

foreach ($fields as $f) {

if ($include) {

$nv = 0;
$nval = 0;

if ($case_sensitive) {
$fv = $f->raw();
} else {
$fv = strtolower($f->raw());

if (is_numeric($fv)) {
$nv = (float) $fv;

if (is_numeric($val)) {
$nval = (float) $val;

// Check each item for match individually
// Return true if matches
// If matches all operators, then true (loop for each case)

switch ($op) {
case “>” :
$include = $fv > $val;
case “#>” :
$include = $nv > $nval;
case “<” :
$include = $fv < $val;
case “#<” :
$include = $nv < $nval;
case “>=” :
$include = $fv >= $val;
case “#>=” :
$include = $nv >= $nval;
case “<=” :
$include = $fv <= $val;
case “#<=” :
$include = $nv <= $nval;
case “*=” :
$include = ( strpos($fv, $val) !== FALSE );
case “~=” :
$include = preg_match(“/(\s|^)”.$val.”(\s|$)/”, $fv );
case “!=” :
$include = $val != $fv;
case “#!=” :
$include = $nval != $nv;
case “^=” :
$include = ( $val == substr($fv, 0, strlen($val)) );
case “$=” :
$include = ( $val == substr($fv, 0, -strlen($val)) );
case “#=” :
$include = ( $nval == $nv );
default: // assume =
$include = ( $val == $fv );

} // endif $include

} // endforeach



if ($include) {
$filtered_items[] = $set_item;

return new MEOW_VirtualFieldSetCollection($filtered_items);


November 10, 2014 at 2:09 pm #3569
Post count: 207

Awesome, thanks for the code. It’s definitely useful to be able to make this more fine-grained. The default behaviour really should be to use the intersection (AND) of the arguments rather than union (OR). I’ll note this does for a future release.

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.

Latest From the Blog

MasterPress 1.4.0 is now available

6th May 2024

This release has a focus on improving compatibility with PHP 8.2. The introduction of inheritance validation to PHP produced a lot of warnings when using MasterPress with PHP 8.2. I have updated most of the problematic code – but some code would have broken in previous PHP versions, so I have temporarily disabled inheritance validation… 

Plugin Requirements

MasterPress requires a minimum of WordPress version 4.9, MySQL 5.6, and PHP version 5.6.20.

We also recommend that PHP is configured to use a memory limit of 64MB per request (128MB may be required for sites with higher complexity).

This plug-in is not compatible with the WordPress.com hosted service.

Three AM