0

I'm working on a site where users are able to publish posts with custom fields associated with them. I want to display meta values from all posts, and include which user created the post where the meta value is coming from.

So far I have been able to display all meta values from all posts. My code:

function get_meta_values( $key = '', $type = 'workout', $status = 'publish' ) {
    global $wpdb;

    if ( empty( $key ) )
        return;

    $r = $wpdb->get_col(
        $wpdb->prepare( "
            SELECT pm.meta_value FROM {$wpdb->postmeta} pm
            LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
            WHERE pm.meta_key = '%s' 
            AND p.post_status = '%s' 
            AND p.post_type = '%s'",
            $key,
            $status,
            $type
        )
    );

    return $r;
}

$workout_leader= get_meta_values( '1_rep', 'workout' );
foreach ( $workout_leader as $value ) { 
    echo $value; 
}

How would I go about retrieving the user meta (e.g. username) for each meta value?

0

Just alter your database query to also grab the user ID, and then return an array of data objects (as opposed to just the meta value):

function get_meta_values( $key, $type = 'workout', $status = 'publish' ) {
    global $wpdb;

    if ( empty( $key ) )
        return;

    $r = $wpdb->get_results(
        $wpdb->prepare( "
            SELECT pm.meta_value, p.post_author FROM {$wpdb->postmeta} pm
            LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
            WHERE pm.meta_key = '%s' 
            AND p.post_status = '%s' 
            AND p.post_type = '%s'",
            $key,
            $status,
            $type
        )
    );

    if ( $r ) {
        $user_ids = wp_list_pluck( $r, 'post_author' );
        cache_users( $user_ids );
    }

    return $r;
}

$workout_leader = get_meta_values( '1_rep', 'workout' );
foreach ( $workout_leader as $data ) {
    echo $data->meta_value;
    echo $data->post_author; // User ID

    // Any other user-related data.
    echo get_the_author_meta( 'display_name', $data->post_author );
}
0

Before retrieve the user, you need to 'save' the information of which user save the meta... WordPress does not store that info, and you can't get something that does not exists.

Saving that info for all meta keys is overwhelming, there are a lot of custom fields WP uses internally, so - probably- you need to choose for which meta key saves author info.

WordPress has an hook 'added_post_meta' that is triggered everytime a custom field is added if it is added using built in functions: add_post_meta or update_post_meta.

You can make use of that hook to save author info

function who_save_what( $mid, $pid, $key, $value ) {
  // arrays of meta fields to save
  // array keys are the meta keys, values is array of post types
  $to_save = array(
    '1_rep' => array( 'workout' ),
    '_thumbnail_id' => array( 'post', 'page', 'workout' ) // just an example
  );
  // check key
  if ( ! array_key_exists( $key, $to_save ) ) return;
  // check post type
  $post = get_post( $pid );
  if ( ! in_array( $post->post_type, $to_save[$key] )  ) return;
  // check user
  if ( ! ( $uid = get_current_user_id() ) ) return;
  // ok, let's save
  remove_filter( current_filter(), __FUNCTION__ ); // avoid recursion
  $who = get_post_meta( $pid, "_who_save_{$key}");
  if ( empty($who) ) $who = array();
  $who[] = array( $mid => $uid );
  $done = update_post_meta( $pid, "_who_save_{$key}", $who );
  add_filter( current_filter(), __FUNCTION__ ); // restore filter
  return $done;
}

add_action( 'added_post_meta', 'who_save_what', 20, 4 );

This function save an array of users that saved a specific meta field using another meta field: "_who_save_{$key}" where $key is the custom field key (e.g. "_who_save_1_rep").

The value of this key is an array of user ids, where the array keys are the meta ids (meta_id in postmeta table). The reason to save an array of users is that you can have multiple fields with same meta key, and in this way you can know which user has saved which specific fields.

Below an example of how to display who have added a meta key, let's say *'1_rep'*:

echo '<p>The "1_rep" key for post ' . $postid . ' was saved by';

$info = get_post_meta( $postid, '_who_save_1_rep', true );
$users = array();
foreach ( $info as $metaid => $userid ) {
  $user = new WP_User( $userid );
  if ( ! $user->exists() ) continue; // users can be deleted...
  $users[] = $user->display_name;
}

if ( empty( $users ) ) {
   echo ' someone that said us goodbye.</p>';
} else {
   echo '</p><ul><li>' . implode( '</li><li>', $users ) . '</li></ul>';
}

If your meta keys are single, i.e. for each post you can have only one *'1_rep'* key, I suggest to leave function as is, and just take first item of array saved in the "_who_save_{$key}" field.

A note: in code above I make the function run only on 'added_post_meta' so it runs when meta are saved, and not when they are updated... if you want maje it run also on update simply add

add_action( 'updated_post_meta', 'who_save_what', 20, 4 );

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.