Jump to content

Filtering an array is breaking my site


aikorei

Recommended Posts

I'm new to the site here, so I hope this is the right place for this post. It's also from a Wordpress site, but since Wordpress isn't the issue (and my [lack of] programming knowledge is), I figured this wouldn't fit on the Wordpress forums very well.

 

So here's my problem. I downloaded a plugin which I'm trying to modify, and it's breaking my site (internal server error), which always makes for a fun day. Here's the piece I'm inserting:

 

// ---START--- Add Buddypress 'Friends' filter.
$wpdb->show_errors();
$k_user_id = $current_user->ID;
$k_friends1 = $wpdb->get_col( "SELECT initiator_user_id FROM $wpdb->prefix . 'bp_friends' WHERE friends_user_id = $k_user_id AND is_confirmed = 1" );
$k_friends2 = $wpdb->get_col( "SELECT friends_user_id FROM $wpdb->prefix . 'bp_friends' WHERE initiator_user_id = $k_user_id AND is_confirmed = 1" );
$k_friends = array($k_friends1, $k_friends2);

foreach($workers as $x) {
if(!in_array($x, $k_friends, TRUE) {
unset($workers[$x]);
}
}
$wpdb->hide_errors();

 

The plugin has already defined the $workers variable, but I'd like to modify that variable by removing any values not contained in either of the two SQL queries. To provide more context, this plugin is an appointments plugin that I'm trying to integrate with Buddypress so that users can schedule appointments with each other, but only if they're friends.

 

I know just enough php to get myself in trouble, so I'm sure there's something that's very obvious to everyone else, but I'm not seeing it...and it's very likely to do with me not understanding exactly how the functions are actually working.

 

Any help would be very much appreciated.

 

Thanks!

Link to comment
Share on other sites

In the future you need to post the error you get as well as your code.

 

if(!in_array($x, $k_friends, TRUE) {

- You're missing a closing parenthesis.

 

 

Also in SQL you shouldn't put quotes around column names. 'bp_friends' makes it a string, and causes an error.

 

ALSO - Your're doing 2 queries when you have absolutely no need to. All of this logic could be done in one query.

Edited by Jessica
Link to comment
Share on other sites

Thanks, Jessica, for the extremely prompt reply. I totally missed the closing ).

 

As for the quotes around column names, the bp_friends is actually the table name. My understanding is that it needs to be a string to append it to Wordpress's table prefix (which in this case is not wp_ as is the case in most WP installs).

 

And honestly, I don't know enough about SQL to put both of those queries into one...not even sure where to start on that.

 

More generally, is my logic on the right track for what I'm attempting to do though?

 

Edit: The error was just a 500 internal server error.

Edited by aikorei
Link to comment
Share on other sites

If you don't see PHP errors, you need to enable error_reporting, set to E_ALL.

 

Table names should not be strings either. If you're having trouble appending them do it outside of the SQL in a separate string, but this should work:

$sql = "SELECT initiator_user_id FROM {$wpdb->prefix}bp_friends WHERE friends_user_id = $k_user_id AND is_confirmed = 1";
$k_friends1 = $wpdb->get_col($sql);

 

If I understand what you're trying to do, this should do it.

 

$sql = "SELECT IF((initiator_user_id = $k_user_id), friends_user_id, initiator_user_id) AS friend_id
FROM {$wpdb->prefix}bp_friends 
WHERE 
(friends_user_id = $k_user_id 
OR initiator_user_id = $k_user_id)
AND is_confirmed = 1";

 

Will get you one array of everyone who is a friend to $k_user_id.

 

 

For the final part "removing any values not contained in either of the two SQL queries" array_intersect should work.

Edited by Jessica
Link to comment
Share on other sites

Thanks so much for the responses, Jessica. I've verified that the SQL values are returning correctly, so thanks very much for the help there.

 

Now the last remaining piece I'm having is in actually removing the values that I don't want there. When I used array_intersect(), I didn't see any difference in the page output. I used

 

$k_workers = array_intersect($workers, $k_friends);

 

and updated subsequent variables to use this new variable, but there was no noticeable change in page output.

 

And just because I'm (apparently) stubborn I went back to my original foreach statement:

 

 foreach($workers as $x) {
  if(!in_array($x, $k_friends, TRUE)) {
   unset($workers[$x]);
  }
 }

 

I have a message printed immediately before and after this message to display the contents of the arrays I'm looking at to see what's actually happening here. When I load the page, the first echo() is printed, but then the page stops and nothing is displayed in the body content...I also don't see the echo() immediately after this. =) I think it's fairly safe to assume something in my foreach statement isn't working right.

 

And the array_intersect() function looks so straightforward it should be easy to see what the problem is...but I didn't see any problem.

Link to comment
Share on other sites

I dunno, I started learning php 2 weeks ago. =)

 

After referring to the manual though, I'm not sure array_dif() is what I want. Doesn't this function only return values from the first array that aren't in the second array? I actually want to only return values that are in the second array, which seems to be the array_intersect() function...unless I'm completely misunderstanding something.

 

Edit: I should probably explain what I do want more clearly. The $workers function comes with the plugin, and is used to generate a dropdown menu. I want to filter this array to only populate IDs that are also the user's "friends" (this comes from the SQL queries above). So if they're in $k_friends, then it's OK to leave them in $workers...otherwise, I'd like them to come out.

Edited by aikorei
Link to comment
Share on other sites

OK, I'm obviously doing something wrong here. What I have total is:

 

// ---START--- Add Buddypress 'Friends' filter.
$wpdb->show_errors();
error_reporting(E_ALL);
$k_user_id = $current_user->ID;
$k_table = $wpdb->prefix . 'bp_friends';
$k_friends1 = $wpdb->get_col( "SELECT initiator_user_id FROM $k_table WHERE friend_user_id = $k_user_id AND is_confirmed = 1" );
$wpdb->print_error();
$k_friends2 = $wpdb->get_col( "SELECT friend_user_id FROM $k_table WHERE initiator_user_id = $k_user_id AND is_confirmed = 1" );
$wpdb->print_error();
$k_friends = array_merge($k_friends1, $k_friends2);
print_r($k_friends);

/*
foreach($workers as $x) {
if(!in_array($x, $k_friends, TRUE)) {
unset($workers[$x]);
}
}
*/

$k_workers = array_intersect($k_friends, $workers);
print_r($k_workers);


$wpdb->hide_errors();
// ---END---

 

When I try to load this page, right now all I get are the two SQL queries displayed above where the content of the page should be (however, no content populates after these queries):

 

WordPress database error: []
SELECT initiator_user_id FROM oyuvfn_bp_friends WHERE friend_user_id = 24 AND is_confirmed = 1
WordPress database error: []
SELECT friend_user_id FROM oyuvfn_bp_friends WHERE initiator_user_id = 24 AND is_confirmed = 1
Array ( [0] => 23 )

 

23 is the only value I'd expect, so that seems to be in working order.

 

However, as soon as I comment out this line thusly,

 

//$k_workers = array_intersect($k_friends, $workers);

 

The page loads just fine. (I've tried the $k_friends and $workers variables in both orders). And what's really frustrating here is that the $k_workers variable isn't even used after this line (the standard $workers variable is still used to populate the dropdown menu).

 

@Barand, to answer your question:

 

perhaps if you give an example or two

 

$workers = array(1,2,3);

$friends = array(2,4)

 

 

$required = ???

 

In this case, $required = 2. I only want to end up with values that are in both arrays (I'm checking the $workers variable against the $k_friends variable for common values...if they're in $workers, but not in $k_friends, they need to go away).

Edited by aikorei
Link to comment
Share on other sites

The page still isn't loading...

 

I reversed the order, as you have shown above, to this:

 

$k_workers = array_intersect($workers, $k_friends);

 

When I uncomment that line, the page still doesn't load. It breaks before reaching the print_r for that array (which is the very next line)....at least I assume so, since it never gets printed on the page.

Link to comment
Share on other sites

It must be other code on the page. You still need to enable error reporting.

 

OK, I admit I don't know how to do that. My second line down has a line that I thought would accomplish this, but obviously it hasn't worked (forgive my ignorance). Where should I look to find the results? (or correctly enable error reporting, for that matter)

Edited by aikorei
Link to comment
Share on other sites

OK, so apparently I have an error_log file on my server. That's good to know...

 

I'm getting a fatal error for that line that's giving me a headache:

 

$k_workers = array_intersect($workers, $k_friends);

 

It says "PHP Catchable fatal error: Object of class stdClass could not be converted to string"

 

As far as I can tell, though, both of those values should be integers.

Edited by aikorei
Link to comment
Share on other sites

Wow. Thanks for bringing up var_dump. The $workers variable is a lot more complicated than I first realized from reviewing the code. $k_friends behaves exactly as I thought it would (since I created that variable, that's fairly fortunate) and only contains a few strings of user IDs:

 

array(3) { [0]=> string(2) "23" [1]=> string(2) "21" [2]=> string(2) "22" }

 

$workers is much more complicated, but the data I want is in there, I just don't know how to get it out:

 

array(7) { [0]=> object(stdClass)#131 (5) { ["ID"]=> string(1) "2" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [1]=> object(stdClass)#127 (5) { ["ID"]=> string(1) "3" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [2]=> object(stdClass)#126 (5) { ["ID"]=> string(2) "15" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [3]=> object(stdClass)#125 (5) { ["ID"]=> string(2) "21" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [4]=> object(stdClass)#113 (5) { ["ID"]=> string(2) "22" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [5]=> object(stdClass)#112 (5) { ["ID"]=> string(2) "23" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } [6]=> object(stdClass)#111 (5) { ["ID"]=> string(2) "24" ["dummy"]=> string(0) "" ["price"]=> string(0) "" ["services_provided"]=> string(3) ":1:" ["page"]=> string(1) "0" } } 

 

So from what I gather, there are 7 objects in this array (which correspond with the 7 "service providers" I have listed on the site for testing). Within each of those objects I find the ID information I want to filter for (e.g.: [5]=> object(stdClass)#112 (5) { ["ID"] => string(2) "23"... the 23 is what I need to be comparing against the $k_friends array to see if it's present).

 

Can I do an array_intersect() in a two-dimensional (or whatever it is) array?

Link to comment
Share on other sites

I tried to modify my foreach loop to the following:

 

 foreach($workers as $innerArray) {
  if(is_array($innerArray)) {
   foreach($innerArray as $x) {
 if(!in_array($x, $k_friends, TRUE)) {
  unset($workers[$innerArray]);
 }
   }
  }
 }

 

The good news is that the page loads when I do this, and seems to function correctly. However, it doesn't actually seem to unset any of the first level arrays. The idea, if I understand right, is that I need to search the nested arrays for my value, and if it's not there then I need to unset the first-level array. I did a var_dump on the $workers array before and after my piece of code and it did exactly nothing. Any insights here?

Link to comment
Share on other sites

After several hours in the trenches of syntax warfare, I finally produced (or stumbled upon):

 

 foreach( $workers as $key => $innerArray ) {
  foreach( $innerArray as $x => $y ) {
   if($x == 'ID' && !in_array($y, $k_friends, TRUE)) {
 unset( $workers[$key] );
   }
  }
 }

 

This does what I need it to do.

 

Jessica, Barand...thanks so much to the both of you for your time and efforts. I really do appreciate it.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.