0

I am trying to save the ID of the current user (if user is logged in) within an array in a post_meta key called "post_is_read" in every post the user reads so I can perform certain actions such as label the post as "unread".

I added this in single page template:

$readers = get_post_meta(get_the_ID(), 'post_is_read');
$current_user = wp_get_current_user();
if (!in_array($current_user->ID, $readers)) {
   $readers[] = $current_user->ID;
    update_post_meta( get_the_ID(), 'post_is_read', $readers, false);
}

Inside the posts loop I added the following code:

$readMeta = get_post_meta( get_the_ID(), 'post_is_read', true );
$current_user = wp_get_current_user();
if ( $readMeta != $current_user->ID ) {
   echo 'unread post';
}

I tried many variations of the first block of code, altered add_post_meta, update_post_meta etc. One problem I recognized is when printing the array stored in the meta key "post_is_read" the output is just "array". I think this is a major problem if it is not the only one in the code.

1 Answer 1

1

You're calling get_post_meta() in two different ways: the first, leaving $single unset (it defaults to false) will get you the full array of meta entries for the given key; the second, setting $single to true, will get only the first item with that key.

What you want, I believe, is an array of user IDs attached to each post in the post_is_read meta.

Here's how I'd attack the problem:

single page template

// Get the list of readers.
$readers = get_post_meta( get_the_ID(), 'post_is_read', true );
// If the value is empty, make sure it's an array.
if ( empty( $readers ) ) {
    $readers = array();
}
$current_user = wp_get_current_user();
if ( ! in_array( $current_user->ID, $readers ) ) {
   // Adds the current user ID to the $readers array.
   $readers[] = $current_user->ID;
   // Updates the 'post_is_read' meta.
   update_post_meta( get_the_ID(), 'post_is_read', $readers );
}

posts loop

$readers = get_post_meta( get_the_ID(), 'post_is_read', true );
if ( empty( $readers ) ) {
    $readers = array();
}
$current_user = wp_get_current_user();
if ( ! in_array( $current_user->ID, $readers ) ) {
   // If the current user hasn't read the post, make a note of it.
   echo 'unread post';
}
5
  • Thank you for the effort put in offering a solution to my problem. I can't try the code at this moment but will do later and let you know. Leaving $single unset was on purpose as I read in wordpress codex it has to be false (as is by default) otherwise the meta_key accepts only one value and replaces it with the latest, if one provided. Something else about $readers = array(); I had the impression, as I read on wordpress documentation that wordpress perceives $readers as an array by default so why declare it?
    – Arg Geo
    Commented Aug 3, 2019 at 23:29
  • Also I do not get why $single is set to true since I am searching for the user's ID which will not necessarily be the first object in the array. Edit: I read this answer (wordpress.stackexchange.com/a/245505/15801) which explains it but still can't get it...
    – Arg Geo
    Commented Aug 3, 2019 at 23:34
  • Thank you very much, code tested and works like a charm! I really appreciate it!
    – Arg Geo
    Commented Aug 4, 2019 at 0:02
  • A post can have multiple metadata set on it, using the same key. So setting $single to true tells WordPress that you want only the first entry to be returned. Leaving it false will return all the entries in an array. Since you want a list of users, it's better to set just one metadata entry, and save it as an array.
    – Pat J
    Commented Aug 4, 2019 at 2:28
  • Also, if the answer works for you, please feel free to mark it as Accepted.
    – Pat J
    Commented Aug 4, 2019 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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