I have this function which contains some custom SQL:
function user_comment_count_by_meta( $user_id, $meta_key )
{
global $wpdb;
$count = 0;
$sql = "SELECT count(*) FROM $wpdb->comments comments INNER JOIN $wpdb->commentmeta meta ON comments.comment_ID = meta.comment_id WHERE comments.user_id = %d AND meta.meta_key = %s";
$count = $wpdb->get_var( $wpdb->prepare( $sql, $user_id, $meta_key ) );
return $count;
}
What it should be doing is counting all the comments for a user that have a particular meta value attached to them and returning that number. So for example if a user has made 20 comments and then 11 of those have the meta value 'accepted' attached to them then the number returned would be 11.
I call the function like so:
<?php $count = user_comment_count_by_meta( get_the_author_meta('id'), 'accepted' ); ?>
However it doesn't return anything. Not sure where I have gone wrong? If any SQL geniuses could help or if anyone can spot a problem it'd be much appreciated. Thanks.
Well,I think that the SQL it's ok, but when you call your function you are using
get_the_author_meta('id')
and this function I think that have other meaning.
If you want the ID from the post author you must use:
get_the_author_ID()
I'm not sure. really.
Related
I am using the "Comments Like Dislike" Plugin in WordPress so my users can like other user's comments. This works fine but I am trying to create an addon plugin that will organize the comments by like count. I have been able to reorganize the comments in this way but the issue I am running in to is that users are no longer able to reply to comments because of this change. The like count is stored in wp_commentmeta like below.
comment_id
meta_key
meta_value
1
cld_like_count
3
My function selects and orders this table by meta value then retrieves the comment ID of each comment. It then uses this array of IDs to organize my comments.
<?php
function like_filter_comments( $comments ) {
return like_organize_comments( $comments );
//return $commentsbylike;
}
add_filter ('comments_array', 'like_filter_comments');
//organize comments so that most liked comments appear first
function like_organize_comments($unorganizedComments){
global $wpdb;
//$allComments = get_comments();
$user_id = 1;
$wpdb_prefix = $wpdb->prefix;
$wpdb_comment = $wpdb_prefix . 'comments';
$wpdb_commentmeta = $wpdb_prefix.'commentmeta';
$meta_commentlike = $wpdb->get_results("SELECT comment_id, meta_key, meta_value FROM $wpdb_commentmeta WHERE meta_key = 'cld_like_count' ORDER BY meta_value DESC;");
$i=0;
foreach($meta_commentlike as $key => $value){
//print_r( $key);
$metav = $value->meta_value;
$comment = $value->comment_id;
$arr[$i++] = $comment; //comment_id listed in order by likes
}
$commentlike = $wpdb->get_results("
SELECT *
FROM $wpdb_comment
WHERE comment_parent
IN (0)
;");
var_dump($commentlike);
return $arr;
}
The function above does successfully organize the comments by like count but it removes the ability to reply to comments. I made an attempt to only select comments with no parent but I am having difficulties because comment_parent is in the wp_comment table and the like count meta value is in the wp_commentmeta table. I've looked into joining the tables together but haven't found any similar columns to merge.
I am currently running the following query on my WordPress website:
PHP:
function get_details($key, $post_id) {
global $wpdb;
$values = $wpdb->get_results( "SELECT meta_value FROM {$wpdb->prefix}new_post_meta WHERE meta_key = '{$key}' AND post_id = '{$post_id}' LIMIT 1" );
return $values[0]->meta_value;
}
ON PAGE:
<?php echo get_details('facebook_url', $post_id); ?>
It is a new custom table which works in the same way as the WP posts meta.
This is run 20 + times on the page so I was wondering if there's a better way to do this?
Currently running the query direct in the database it takes 0.5128 sec and the database table is 36MB in size.
The query is really slowing the site down.
Thanks to shadow for stating the obvious but it worked:
public function get_meta_data() {
$meta_keys = array(
//META KEYS GO HERE IN ARRAY
);
$mks = implode("', '", $meta_keys);
//Get Results
global $wpdb;
$results = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->prefix}resorts_meta WHERE meta_key IN ('{$mks}') AND post_id = '{$this->id}'", OBJECT_K );
foreach($results as $key => $value) {
$this->$key = $value->meta_value;
}
return "SELECT meta_key, meta_value FROM {$wpdb->prefix}new_post_meta WHERE meta_key IN ('{$mks}') AND post_id = '{$this->id}'";
I then created a function to display the results in $this->variables like so:
public function get_meta( $key ) {
return $this->$key;
}
And then stored get_meta_data in the construct function.
Thanks Shadow.
I upgraded my old site from wordpress version 3.4 to 4.4 recently. Suddenly I am getting a PHP warning as per below:
Warning: Missing argument 2 for wpdb::prepare(), called in ...../wp-content/themes/...functions/admin-functions.php on line 1543 and defined in .......public/wp-includes/wp-db.php on line 1246
Below are the codes for admin-functions.php:
global $wpdb;
$query = "SELECT *,count(*) AS used FROM $wpdb->postmeta WHERE meta_key = '_wp_page_template' AND meta_value = '$filename' GROUP BY meta_value";
$results = $wpdb->get_row($wpdb->prepare($query),'ARRAY_A'); // Select thrid coloumn accross
if(empty($results))
return false;
and wp-db.php
public function prepare( $query, $args ) {
if ( is_null( $query ) )
return;
You need to use placeholders and add the variable as an argument to prepare,%s is a placeholder for string value,assuming it is string from your quotes
$query = "SELECT *,count(*) AS used FROM $wpdb->postmeta
WHERE meta_key = '_wp_page_template' AND meta_value = %s
GROUP BY meta_value";
$results = $wpdb->get_row($wpdb->prepare($query,$filename),'ARRAY_A'); // Select thrid coloumn accross
I would recommend reading the documentation for $wpdb->prepare.
Prepare requires at least two arguments to be passed in. The first is the query, using placeholders (%s for a string and %d for a number), and the second is the list of variables / values to place into the query instead of the placeholders.
For your specific case, I'm demonstrating in a bit longer format so you can see clearly:
global $wpdb;
// Old query. Let's get it ready for prepare...
// $query = "SELECT *,count(*) AS used FROM $wpdb->postmeta WHERE meta_key = '_wp_page_template' AND meta_value = '$filename' GROUP BY meta_value";
// New query, ready for prepare:
$query = "SELECT *,count(*) AS used FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s GROUP BY meta_value";
// Now we pass that into prepare, along with the two values we want replaced
$wpdb->prepare($query, '_wp_page_template', $filename);
// And we execute the query...
$results = $wpdb->get_row($query,'ARRAY_A');
Note that you can use the placeholders for as many values as you want, but the idea is that you use them for any value that is user input. If the value may be posted through a form, for example, you absolutely want to use prepare on that value. Example:
$post_id = $_POST['post_id'];
$query = 'SELECT * FROM $wpdb->postmeta WHERE post_id = %d';
$query = $wpdb->prepare($query, $post_id);
Hopefully this helps!
You need to pass $meta_key as second argument.
eg:-
<?php
// set the meta_key to the appropriate custom field meta key
$meta_key = 'miles';
$allmiles = $wpdb->get_var( $wpdb->prepare(
"
SELECT sum(meta_value)
FROM $wpdb->postmeta
WHERE meta_key = %s
",
$meta_key
) );
echo "<p>Total miles is {$allmiles}</p>";
?>
so here your second second argument is $filename.
Reference :- Class Reference / wpdb
Wordpress database, bit stuck on this one.
I'm using the following to get the ID of the current user.
$user_ID = get_current_user_id();
This returns something like this :
15
Now I try to find the matching value of $user_ID in the field show_user_list The data in this field is stored in an array.
Which looks something like this :
a:2:{i:0;s:2:"29";i:1;s:2:"15";}
This is the query i'm running (along with a set of conditions) :
global $wpdb; $result = $wpdb->get_results( "SELECT post_id FROM wp_postmeta WHERE show_user_list IN (' . implode(',', $user_ID) . ' AND post_type = 'show' AND post_status = 'publish'" );
And then I'm trying to echo the value of the matching post_id with this :
foreach ( $result as $unique ) {
echo $unique->post_id;
}
But it's not returning anything. I know I must be making a mistake while dealing with the array but I don't know where I'm going wrong?
looks like you have stored a serialized array in the show_user_list field, so it will be a hustle to search for values into using a db query.
In the model you described, you have to select all the rows from wp_postmeta that match "post_type = 'show' AND post_status = 'publish'", then manually filter results that do not have the user id in the unserialized show_user_list field.
You might try something like :
in_array($user_ID, unserialize($row->show_user_list))
Also, I noticed multiple errors in your query: string not properly concatenated with PHP code and the right parenthesis of the IN clause not closed.
Regards,
same
EDIT
Here is how I would solve your problem providing info you have given :
$user_ID = get_current_user_id();
global $wpdb;
$results = $wpdb->get_results("SELECT post_id, show_user_list FROM wp_postmeta WHERE post_type = 'show' AND post_status = 'publish'");
$user_post_ids = array();
foreach ($results as $post) {
if (in_array($user_ID, unserialize($post->show_user_list))) {
$user_post_ids[] = $post->post_id;
}
}
Hope this helps !
I have a Mysql query set outside the wordpress loop, like the one below, which doesn't work. I would like to know how can I filter the sql results based on the author that created the post.
global $post;
$post_author = $post->post_author;
$sQuery = "SELECT DATE_FORMAT((post_date), '%M/%Y') 'Month',
FROM wp_posts p WHERE p.post_author = '$post_author'
Any assistance is appreciate it.
Thank you,
You have an extra comma after 'Month'. Try this:
$post_author = $post->post_author;
$sQuery = "SELECT DATE_FORMAT((post_date), '%M/%Y') 'Month' FROM wp_9691posts p WHERE p.post_author = '$post_author'";
I also added the final " to enclose the query string.