Skip to content

Instantly share code, notes, and snippets.

@EdHurtig
Created May 29, 2014 16:29
Show Gist options
  • Save EdHurtig/f95bfd9011d31a18d60a to your computer and use it in GitHub Desktop.
Save EdHurtig/f95bfd9011d31a18d60a to your computer and use it in GitHub Desktop.
Add the ability to get post meta from the network_postmeta table without having to switch_to_blog or jump through hoops
<?php
/**
*
* Gets the post meta for a specific post from the post indexer table
*
* @param int|post $post The ID of the Post that you want the meta for
* @param string $key (optional) The meta key of the data you want
* @param bool $single (optional) Whether to return a single Value
* @param int|bool $blog_id The ID of the blog that the post is located on
*
* @return array|bool|mixed|string|void ... Whatever get_post_meta() returns normally given parameters above
*/
function network_get_post_meta( $post, $key = '', $single = false, $blog_id = false ) {
global $wpdb;
$meta_type = 'post';
// If you didn't specify a blog ID
if ( ! $blog_id ) {
if ( isset( $post->BLOG_ID ) ) {
// Well if you passed a Post resulting from network_query() then use that BLOG_ID
$blog_id = $post->BLOG_ID;
} else {
// Use the Current Blog ID
$blog_id = get_current_blog_id();
}
}
// If you passed in a Post object, lets get the ID
if ( is_object( $post ) ) {
$post = $post->ID;
}
if ( ! $post = absint( $post ) ) {
return false;
}
/**
* Filter whether to retrieve metadata of a specific type.
*
* The dynamic portion of the hook, $meta_type, refers to the meta
* object type (comment, post, or user). Returning a non-null value
* will effectively short-circuit the function.
*
* @since 3.1.0
*
* @param null|array|string $value The value network_get_metadata() should
* return - a single metadata value,
* or an array of values.
* @param int $object_id Object ID.
* @param string $meta_key Meta key.
* @param string|array $single Meta value, or an array of values.
*/
$check = apply_filters( "network_get_{$meta_type}_metadata", null, $post, $key, $single );
if ( null !== $check ) {
if ( $single && is_array( $check ) ) {
return $check[0];
} else {
return $check;
}
}
// Check Cache first
$meta = wp_cache_get( "network_meta_{$blog_id}-{$post}", $meta_type . '_meta' );
// if nothing found in cache then go to DB
if ( ! $meta ) {
// Query EVERYTHING based on $blog_id and $post_id
$query = $wpdb->prepare( "SELECT meta_id, meta_key, meta_value FROM {$wpdb->base_prefix}network_postmeta WHERE blog_id = %d AND post_id = %d", $blog_id, $post );
$meta = $wpdb->get_results( $query, ARRAY_A );
// Now set everything in the cache for future calls (even in this request)
wp_cache_set( "network_meta_{$blog_id}-{$post}", $meta );
}
// If there's nothing then get out
if ( empty( $meta ) ) {
if ( $single ) {
return '';
} else {
return array();
}
}
// You wanted Everything... here's everything
if ( ! $key ) {
return $meta;
}
// Now filter everything but $key
array_filter( $meta, function ( $row ) use ( &$key ) {
return $row['meta_key'] == $key;
} );
// Check to see if the key was included
if ( ! empty( $meta ) ) {
if ( $single ) {
return maybe_unserialize( $meta[0]['meta_value'] );
} else {
return array_map( function ( $row ) {
return maybe_unserialize( $row['meta_key'] );
}, $meta );
}
} else {
// Key isn't in meta... return the nothing stuff again per wp spec
if ( $single ) {
return '';
} else {
return array();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment