WordPress Order by using a meta_value not resulting in the correct order - wordpress-theming

There is a custom post type called guides and this has a meta post_views_count. The count is incremented each time someone visits a page of this post type. The data is being stored accurately.
Now I want to get a list of all posts ordered by the post_views_count so that I can see which article has been viewed the most.
Here is my query.
$query = new WP_Query( array(
'post_type' => 'guides',
'post_status' => 'publish',
'suppress_filters' => false,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'post_views_count',
'compare' => '>',
'value' => 0
)
),
'meta_key' => 'post_views_count',
'orderby' => 'meta_value post_date',
'order' => 'ASC',
) );
The problem is that meta_value in WordPress is stored as longtext, making it difficult to order a numeric value.
Any suggestions on how to get this working?

looks like it is sorting it as text, you will have to add 'meta_type' => 'NUMERIC', in your query so that meta_value is converted to number before sorting i guess. also try meta_value_num instead of meta_value in orderby
try
// Sort by numeric meta
'meta_key' => 'post_views_count',
'meta_type' => 'NUMERIC',
'order' => 'ASC',
'orderby' => 'meta_value_num',

Related

How to get WooCommerce products from database based on multiple attributes

I want to get related products based on some criteria on product attributes like, the same sku, ean and gtin codes. But my query doesn't return any results. I tried different ways to query the database but all fail. Here is my query.
$sku = $product->get_sku();
$ean = $product->get_attribute( 'EAN' );
$gtin = $product->get_attribute( 'GTIN' );
$query = new WP_Query( array(
'post_type' => array('product'),
'posts_per_page' => 20,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_sku',
'value' => $sku,
'compare' => '='
)
),
'tax_query' => array(
array(
'taxonomy' => 'pa_ean',
'field' => 'value',
'terms' => $ean,
'operator' => '=',
),
array(
'taxonomy' => 'pa_gtin',
'field' => 'value',
'terms' => $gtin,
'operator' => '=',
)
)
) );
By the way, if a product has ean code than it doesn't have a gtin and vice versa. It always has a sku which is unique to it self. But I have it added as a check to check if query at least returns value.
I can't find good documentary on this topic and hope someone here can help.

Ordering by multiple ACF fields

I've seen a few questions similar to this but I still can't get things working so I thought I'd ask.
I have a Custom Post Type called 'Course'. This CPT has a custom field called 'date' which is either past, future or not set (null).
I am trying to write a query that hides the past courses, then shows future courses (ordered by date, soonest first) and then shows the courses where the date is not set (placeholder courses).
My plan was to add a 'placeholder_course' field to the course CPT and the date box would only appear if this was set to false. That way all of the placeholders would have a value of 1 for this field so I could sort by this to have them appear at then end, and then sort by the date to order the values in the date field correctly.
This is what I've been using:
<?php
$today = current_time('Ymd');
$args = array(
'post_type' => 'course',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
'placeholder' => array(
'key' => 'placeholder_course',
'compare' => '=',
'value' => '1
),
'future_dates' => array(
'key' => 'date',
'compare' => '>=',
'value' => $today,
)
),
'orderby' => array(
'placeholder' => 'ASC',
'future_dates' => 'ASC',
),
);
?>
but the ordering is still coming out muddled. I'm pretty sure I've just done something wrong in the query, can anyone shed any light please?
Set up a true/false field for your placeholder value (if no date is set you can check on it) then the following code runs through either future dates or any post with the placeholder true/false value set to true
UPDATE: your'e probably gonna have to do this with 2 queries.
$args = array(
'post_type' => 'course',
'posts_per_page' => -1,
'meta_key' => 'date',
'meta_query' => array(
array(
'key' => 'date',
'value' => $today,
'compare' => '>=',
),
),
'orderby'=> 'meta_value_num',
'order' => 'ASC'
);
$args2 = array(
'post_type' => 'course',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'placeholder_course',
'value' => true,
'compare' => '=',
),
),
'order' => 'ASC'
);

Fetch random row from group by query (mysql) in Cakephp

I have a table 'activities' and the columns are grouped by three of its attributes. Now I want to fetch Activity ID that is randomly selected from all the set of groups. The query is as follows:
$act = $this->find('all', array('conditions' => $cond,
'limit' => $limit,
'fields' => array('count(*) as count, Activity.id as id'),
'page' => $page,
'group' => $group,
));
These are the things I tried and none of them worked.
1. Create a self join which should have random records
$this->bindModel(array(
'belongsTo' => array(
'Random' => array(
'className' => 'Activity',
'order' => 'rand()',
'foreignKey' => 'id',
'fields' => 'Random.id'
)
)
));
This failed because the rand() order is appended in the end which simply randomizes all fetched activities.
Added a join option
'joins' => array(
array(
'table' => 'activities',
'alias' => 'Random',
'type' => 'LEFT',
'conditions' => array(
'Activity.id = Random.id'
),
'fields' => 'Random.id',
'order' => 'rand()'
)
This also didn't work as order value is not parsed by Cake
Tried to add condition
'Activity.id >= floor(rand() * (max(Activity.id) - min(Activity.id)) - min(Activity.id))'
Gave a mysql error
Please help me out
Assuming that your query is working:
$act = $this->find('all', array('conditions' => $cond,
'limit' => $limit,
'fields' => array('count(*) as count, Activity.id as id'),
'page' => $page,
'group' => $group,
'order' => 'rand()',
'limit' => '1' // if you only want one random activity ID
));
Ok finally figured it out. We need to hack the way cake php works. In place of table name, I wrote a query to fetch randomly ordered records. Also notice the join type is 'right'. Left join wont produce randomly sorted list
$activities = $this->find('all', array('conditions' => $cond,
'page' => $page,
'limit' => $limit,
'fields' => array('count(*) as count, Random.id as id, max(Activity.modified) as Modified'),
'group' => $group,
'order' => 'Modified desc',
'joins' => array(
array(
'table' => '(select * from activities order by rand())',
'alias' => 'Random',
'type' => 'RIGHT',
'conditions' => array(
'Activity.id = Random.id'
),
)
)
));

meta_query, how to search using both relation OR & AND?

Resolved: See answer below.
I have a custom post type called BOOKS. It has several custom fields, named: TITLE, AUTHOR, GENRE, RATING. How do I fix my meta_query code below so that only books that have the search word in the custom fields: title, author, genre WITH EXACTLY the rating specified in my search form, gets displayed in the results?
I have made a custom search form; a text area that will search through the title, author and genre; and a dropdown that will search for the rating. The meta_query I made below only searches through the title, author, and genre. But I am now stumped in how to add the code for the rating.
This is how I visually imagined it with meta_query relation:
(title OR author OR genre) AND rating
$args = array(
'relation' => 'OR',
array(
'key' => 'title',
'value' => $searchvalue,
'compare' => 'LIKE'
);
array(
'key' => 'author',
'value' => $searchvalue,
'compare' => 'LIKE'
);
array(
'key' => 'genre',
'value' => $searchvalue,
'compare' => 'LIKE'
);
),
array(
'relation' => 'AND',
array(
'key' => 'rating',
'value' => $ratingvalue,
'compare' => '=',
'type' => 'NUMERIC'
));
I would extremely appreciate your help and advice.
I found the solution with some help.
The code below worked perfectly.
$args => array(
'relation' => 'AND',
array(
'relation' => 'OR',
array(
'key' => 'title',
'value' => $searchvalue,
'compare' => 'LIKE'
),
array(
'key' => 'author',
'value' => $searchvalue,
'compare' => 'LIKE'
),
array(
'key' => 'genre',
'value' => $searchvalue,
'compare' => 'LIKE'
)
),
array(
'key' => 'rating',
'value' => $ratingvalue,
'compare' => '=',
'type' => 'NUMERIC'
)
)
);
After a bit trial and error I find a solution to this. This is logical I mean meta_query does not supports the array for field "key", but giving the array in "key", I'm getting the perfect solution. I may be sound crazy but it's working like charm.
$args => array(
'relation' => 'AND',
array(
'key' => array('title','author','genre',),
'value' => $searchvalue,
'compare' => '='
),
array(
'key' => 'rating',
'value' => $ratingvalue,
'compare' => '=',
'type' => 'NUMERIC'
)
)
You only get a warning for "trim()" as we are passing an array instead of a string. Suppress that warning or Please add something if you find a better solution.

SQL request does not work correctly

my problem is very simple. I have a table named 'articles' and I'd like to get the first three recent articles order DESC. But I want also these articles be displayed if their publication date is older or equal to today. So I've had an other condition in my request. My cakephp code is the following :
$this->set('lastArticles', $this->Article->find('all', array(
'conditions' => array('Article.visible' => true),
'Article.publication_date <= ' => date('Y-m-d'),
'order' => array('Article.creation_date DESC', 'Article.id DESC'),
'limit' => 3
)));
But the problem is even if the articles with a publication date > date('Y-m-d') these ones are displayed too! Does anyone have an idea ? Thanks in advance for your answer.
Looks like your publication_date condition isn't in the conditions array. Your code should look like this:
$this->set('lastArticles', $this->Article->find('all',
array(
'conditions' => array(
'Article.visible' => true,
'Article.publication_date <= ' => date('Y-m-d')
),
'order' => array(
'Article.creation_date DESC',
'Article.id DESC'
),
'limit' => 3
)));
A bit of extra indentation and whitespace is your friend here.
See this
$conditions = array(
'Article.visible' => true,
'Article.publication_date <= ' => date('Y-m-d')
);
$order = array('Article.creation_date DESC', 'Article.id DESC');
$lastArticles = $this->Article->find('all', array(
'conditions' => $conditions,
'order' => $order,
'limit' => 3
);
$this->set('lastArticles', $lastArticles);