3

This is my code:

$args = array (
    'order'      => 'DESC',
    'include'  => get_user_meta($author->ID, 'the_following_users', true)
);

$wp_user_query = new WP_User_Query( $args );

$users = $wp_user_query->get_results();

if ( ! empty( $users ) ) {
    foreach ( $users as $user ) {
        // Get users
    }
} else {
    echo 'Error.';
}

The user meta 'the_users' may be empty so if it's empty it's got to me all registered users if not empty it's print the users that I need.

The problem that if ( ! empty( $users ) ) { } is not reading if 'include' is empty or not, I know I can make a variable and check first if the variable is empty or not but I don't need this I want to check if 'include' is empty by using '$wp_user_query->get_results()'.

EDIT:

As Nicolai answer we can replace true to false from get_user_meta code and the problem will be solved and if the include is empty the WP-User_Query will return a false and print error.

The problem now that if include not empty so the code must be working without any issues but that does not happen it ignores the users that stored in 'the_users' user meta and print only current user.

Here's the value of 'the_users' user meta:

a:19:{i:0;s:2:"89";i:3;s:3:"105";i:4;s:2:"74";i:5;s:3:"111";i:6;s:3:"167";i:7;s:2:"83";i:8;s:2:"54";i:9;s:2:"87";i:10;s:2:"85";i:11;s:2:"77";i:13;s:2:"82";i:14;s:2:"60";i:15;s:3:"149";i:16;s:3:"160";i:17;s:2:"71";i:18;s:1:"3";i:19;s:1:"2";i:20;s:3:"121";i:21;s:2:"57";}

Here's how i stored 'the_users' user meta data:

$the_following_users = get_user_meta($the_follower, "the_following_users", true);

if(!in_array($user_follow_to, $the_following_users) && is_array($the_following_users)){
    $the_following_users[] = $user_follow_to;
} else {
    $the_following_users = array($user_follow_to);
}

update_user_meta($the_follower, "the_following_users", $the_following_users);
  • @Nicolai really thank you very much yes the solution is to replace true to false. – Michel Dec 27 '17 at 23:46
  • @Nicolai can you post that as an answer? – Tom J Nowell Dec 27 '17 at 23:48
  • My pleasure. @TomJNowell Done. – Nicolai Dec 27 '17 at 23:53
  • 1
    @Michel you noted above that Nicolai's solution worked for you, yet you commented on Nicolais answer that there's a problem, can you edit your question to be more specific, and include examples? It's difficult to parse the language you've written, and so it's not clear if it does indeed answer your question, or if your question is complete – Tom J Nowell Dec 28 '17 at 0:21
  • @TomJNowell I edited the question now please take a look. – Michel Dec 28 '17 at 5:01
2

I think the problem here is that in the process of violating this rule, you've created confusion and problems:

do 1 thing per statement, 1 statement per line

Coupled with another problem:

Passing arrays to the APIs which get stored as serialised PHP ( security issue )

And another:

Always check your assumptions

it ignores the users that stored in 'the_users' user meta and print only current user.

That last one is the killer here. You never check for error values on get_user_meta, leading to errors. Users don't start out with the_users meta, it has to be added.

Run through this code in your mind, e.g.:

$the_following_users = ''; //get_user_meta($the_follower, "the_following_users", true);

if(!in_array($user_follow_to, $the_following_users) && is_array($the_following_users)){
    $the_following_users[] = $user_follow_to;

Here there is no check on $the_following_users, which may not be an array at all, but a false or an empty string.

So lets fix the saving:

$the_following_users = get_user_meta($the_follower, "the_following_users", true);
if ( empty( $the_following_users ) ) {
    $the_following_user = array();
}

Then lets simplify the next part:

$the_following_users[] = $user_follow_to;

And fix the saving so that it's not a security risk:

$following = implode( ',', $the_following_users );
update_user_meta($the_follower, "the_following_users", $following );

Finally, lets move to the frontend:

Firstly, we assume the get_user_meta works, but never check if this is true:

$args = array (
    'order'      => 'DESC',
    'include'  => get_user_meta($author->ID, 'the_following_users', true)
);

What if the user has never followed anybody before? What if they unfollowed everyone? That would break everything! So lets fix that and switch it over to the comma separated list format:

$include = get_user_meta($author->ID, 'the_following_users', true);
if ( empty( $include ) ) {
    // the user follows nobody, or has not followed anybody yet!
} else {
    // turn the string into an array
    $include = explode( ',', $include );
    $args = array (
        'order'      => 'DESC',
        'include'  => $include
    );
    // etc...
}

A Final Note

Your loop looks like this:

foreach ( $users as $user ) {
    // Get users
}

But you never share the code inside the loop, which could be why you're having issues. For example, the_author always refers to the author of the current post. If you want to display information about the $user, you would need to pass its ID, or user the public properties, e.g.

foreach ( $users as $user ) {
    // Get users
    echo esc_html( $user->first_name . ' ' . $user->last_name );
}
  • Thank you but can you explain to me why you add explode and implode you say that's for security but i can't understand what's the risk to store and get the meta without implode and explode. – Michel Dec 28 '17 at 14:46
  • When you take serialised PHP and deserialise it, any objects inside that string get created as expected. People forget though that their constructors and wakeup functions also get run, which can lead to attack vectors. By sneaking in serialised PHP containing unexpected objects where none were expected, you can run code on the server. Storing as a comma separated list avoids this while also making it easier to debug – Tom J Nowell Dec 29 '17 at 2:57
4

The include parameter of WP_User_Query expects an array as argument. So set the $single parameter of get_user_meta to false. Or don't use it, because false is the default.

// USE
get_user_meta( $author->ID, 'the_users', false )
// OR
get_user_meta( $author->ID, 'the_users' )
  • 1
    There's a small problem that if we do this the users that will print is current user only to solve this problem I must add true again to print all the users that exist in this user meta. This is the user meta a:3:{i:9;i:9;i:57;i:57} – Michel Dec 28 '17 at 0:00
  • NOTE: It's working yes and if the meta is empty it's return false and that's what I need but the problem as I explain at the previous comment that it's getting current user only. – Michel Dec 28 '17 at 0:01
  • I edited the question now please take a look and thank you for your efforts. – Michel Dec 28 '17 at 5:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.