Get Woocommerce customer order language - mysql

I'm developing a complementary plugin for woocommerce.
I have a sql request that gets all the order and customer info, but i need to get the language from the order.
How can i detect the language was using a customer when he made an order? Is it registered somewhere?
In other CMS like prestashop it's stored as id_lang in orders and customer tables.

Without getting into which plugin you will chose and how it operates, here is how you would save some extra data to the order.
// save the extra field when checkout is processed
function kia_save_extra_checkout_fields( $order_id, $posted ){
$language = detect_language_with_your_plugin_of_choice() ? detect_language_with_your_plugin_of_choice() : "en";
update_post_meta( $order_id, '_order_language', $language );
}
add_action( 'woocommerce_checkout_update_order_meta', 'kia_save_extra_checkout_fields', 10, 2 );
And because I had an awful time the one time I tried to use WPML, maybe consider checking out Multilingual Press.

Finally solved, both solutions are OK.
With WPML plugin you can get the value in the table postmeta with the meta_key = wpml_language
Just added a left join in my SQL query:
SELECT O.ID as id_order, O.post_date_gmt as date, M.meta_value as email, M2.meta_value as firstname, M3.meta_value as lastname, M4.meta_value as iso_code
FROM ".$prefix."posts O
LEFT JOIN ".$prefix."postmeta M ON M.post_id = O.ID AND M.meta_key = '_billing_email'
LEFT JOIN ".$prefix."postmeta M2 ON M2.post_id = O.ID AND M2.meta_key = '_billing_first_name'
LEFT JOIN ".$prefix."postmeta M3 ON M3.post_id = O.ID AND M3.meta_key = '_billing_last_name'
LEFT JOIN ".$prefix."postmeta M4 ON M3.post_id = O.ID AND M4.meta_key = 'wpml_language'
WHERE O.post_type = 'shop_order' AND O.post_status = 'wc-completed'

Related

Modifying MySQL Query for WpDataTables

I am building a table in WpDataTables that involves two custom post types: 'applicants' and 'reviews'. I am trying to create a table that shows all of the applicants that have either been reviewed by the current user (reviewer) who is viewing the WpDataTable. Each applicant can have one or more reviews.
This query runs exactly like I want it to in MySQL, however, WpDataTables does not like it for some reason. I believe it is because of the subquery.
SELECT a.ID, r.post_title, a.post_title, a.guid, r.post_type, a.post_type, r.post_author,
b.meta_value review_app_score,
c.meta_value review_app_comment
FROM (SELECT * FROM `wppm_2_posts` WHERE post_author = 1 AND post_type = 'reviews' AND post_status = 'publish') as r
RIGHT JOIN `wppm_2_posts`as a ON r.post_title = a.ID
LEFT JOIN `wppm_2_postmeta` b ON r.ID = b.post_id AND b.meta_key='review_app_score'
LEFT JOIN `wppm_2_postmeta` c ON r.ID = c.post_id AND c.meta_key='review_app_comment'
WHERE a.post_type = 'applicants'
AND a.post_status = 'publish'
Here is what the MySQL results:
https://i.stack.imgur.com/KzvHt.png
This is exactly what I am needing, except I need it to work in WpDataTables.
The reason is that I am looking to take advantage of their dynamic placeholder (%CURRENT_USER_ID%) instead of the '1' in the subquery above for post_author.
Such as:
(SELECT * FROM `wppm_2_posts` WHERE post_author = %CURRENT_USER_ID% AND post_type = 'reviews' AND post_status = 'publish')
Is there another way I could write this without using a subquery? Or there is another way to build this without needing the dynamic placeholder such as PHP?
Any help is appreciated.
Here is the professional way (AKA it wasn't me) of writing the query. Not sure if it will help anyone else but hopefully it will.
SELECT
APPLICANTS.ID AS applicants_id
,APPLICANTS.post_title AS applicants_post_title
,APPLICANTS.guid AS applicants_guid
,APPLICANTS.post_type AS applicants_post_type
,REVIEWS.post_author AS reviews_author_id
,REVIEWS.post_type AS reviews_post_type
,REVIEWS.post_title AS reviews_post_title
,R_APP_SCORES.meta_value AS review_app_score
,R_APP_COMMENTS.meta_value AS review_app_comment
FROM
`%WPDB%posts` AS APPLICANTS
LEFT JOIN
`%WPDB%posts` AS REVIEWS ON
(REVIEWS.post_author = %CURRENT_USER_ID%) AND
(REVIEWS.post_title = APPLICANTS.ID) AND
(REVIEWS.post_type = 'reviews') AND
(REVIEWS.post_status = 'publish')
LEFT JOIN
`%WPDB%postmeta` R_APP_SCORES ON
(R_APP_SCORES.post_id = REVIEWS.ID) AND
(R_APP_SCORES.meta_key = 'review_app_score')
LEFT JOIN
`%WPDB%postmeta` R_APP_COMMENTS ON
(R_APP_COMMENTS.post_id = REVIEWS.ID) AND
(R_APP_COMMENTS.meta_key = 'review_app_comment')
WHERE
(APPLICANTS.post_type = 'applicants') AND
(APPLICANTS.post_status = 'publish')

try to count this online user's order which is processing

I want to limit each user to register only one order per day.
To do this, I need to check each user's order before registering whether this user has any 'wp-processing' order or not?
I wrote below MySQL query in PHP, but it doesn't work.
I printed value of '$sql_count_from_status' and try it in phpmyadmin, SQL tab to find the error.
Value of the variable was:
SELECT count(ID) FROM wp_posts p LEFT JOIN wp_postmeta m ON p.ID=m.post_id WHERE p.post_status LIKE 'wc-processing' AND p.post_type LIKE 'shop_order' AND m.meta_key LIKE '_customer_user' AND m.meta_value LIKE '100577';
and showed me zero in phpmyadmin as result. Now I know the query has problem, because I had 'processing order' for user 100577.
function get_orders_count_from_status( $status , $this_user_id){
global $wpdb;
// We add 'wc-' prefix when is missing from order staus
$status = 'wc-' . str_replace('wc-', '', $status);
$sql_count_from_status = "
SELECT count(ID) FROM {$wpdb->prefix}posts p
LEFT JOIN {$wpdb->prefix}postmeta m
ON p.ID=m.post_id
WHERE p.post_status LIKE '$status' AND p.post_type LIKE 'shop_order'
AND m.meta_key LIKE '_customer_user'
AND m.meta_value LIKE '".$this_user_id."';";
return $wpdb->get_var($sql_count_from_status);
}
Here's an example of a plausible query (although counting on a LEFT JOIN is a bit strange):
SELECT count(*)
FROM {$wpdb->prefix}posts p
LEFT
JOIN {$wpdb->prefix}postmeta m
ON m.post_id = p.ID
AND m.meta_key = '_customer_user'
AND m.meta_value = :this_user_id
WHERE p.post_status LIKE :status
AND p.post_type = 'shop_order'

Wordpress Woocommerce Subscription - Get Total Active Subscriptions By Product

We are building a simple dashboard status plugin that will show the total "Active" subscriptions for a specific product.
I'm using the following function to grab the total active subscriptions, but the numbers aren't lining up due to switched subscriptions. How do I account for the switch subscriptions?
function get_active_subscriptions_count( $product_id) {
global $wpdb;
// return the active subscriptions for a defined product ID
return $wpdb->get_var("
SELECT COUNT(p.ID)
FROM {$wpdb->prefix}posts as p
LEFT JOIN {$wpdb->prefix}posts AS p2 ON p.post_parent = p2.ID
LEFT JOIN {$wpdb->prefix}postmeta AS pm ON p2.ID = pm.post_id
LEFT JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON pm.post_id = woi.order_id
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
WHERE p.post_type LIKE 'shop_subscription'
AND p2.post_type LIKE 'shop_order' AND woi.order_item_type LIKE 'line_item'
AND pm.meta_key LIKE '_customer_user'
AND woim.meta_key = '_product_id'
AND woim.meta_value = '$product_id'
AND p.post_status LIKE 'wc-active'
");
}
What can I do to account for the switch subscriptions? What am I missing in the query?

SQL Inner Query WHERE clause access to Outer Query tables

Good morning -
This is my first post here, after many years using SO as a very useful resource.
I've run into a problem with a complex (for me) query I'm pulling together for a wordpress site running woocommerce to process orders. I'm trying to add a filter to the order list which filters orders which contain products in a particular product category.
I'm afraid I've gotten in over my head with this query which joins a variety of meta tables on inner queries in order to get at the information I need in order to determine the product's category.
The problem is that I can't get the scoping rules to work in order to access required outer table information in the inner queries.
The query is:
SELECT SQL_CALC_FOUND_ROWS
wp_ot6q6i_posts.ID
FROM
wp_ot6q6i_posts
WHERE
1 = 1 AND YEAR(wp_ot6q6i_posts.post_date) = 2015 AND MONTH(wp_ot6q6i_posts.post_date) = 12 AND wp_ot6q6i_posts.post_type = 'shop_order' AND(
(
wp_ot6q6i_posts.post_status = 'wc-pending' OR wp_ot6q6i_posts.post_status = 'wc-processing' OR wp_ot6q6i_posts.post_status = 'wc-on-hold' OR wp_ot6q6i_posts.post_status = 'wc-completed' OR wp_ot6q6i_posts.post_status = 'wc-cancelled' OR wp_ot6q6i_posts.post_status = 'wc-refunded' OR wp_ot6q6i_posts.post_status = 'wc-failed'
)
) AND EXISTS(
SELECT
t2.PROD_ID
FROM
(
SELECT
wp_ot6q6i_woocommerce_order_itemmeta.meta_value AS PROD_ID
FROM
wp_ot6q6i_woocommerce_order_items
LEFT JOIN
wp_ot6q6i_woocommerce_order_itemmeta
ON
wp_ot6q6i_woocommerce_order_itemmeta.order_item_id = wp_ot6q6i_woocommerce_order_items.order_item_id
WHERE
wp_ot6q6i_woocommerce_order_items.order_item_type = 'line_item' AND wp_ot6q6i_woocommerce_order_itemmeta.meta_key = '_product_id' AND wp_ot6q6i_posts.ID = wp_ot6q6i_woocommerce_order_items.order_id
) t1
INNER JOIN
(
SELECT DISTINCT
wposts.ID AS PROD_ID
FROM
wp_ot6q6i_posts wposts
LEFT JOIN
wp_ot6q6i_postmeta wpostmeta
ON
wposts.ID = wpostmeta.post_id
LEFT JOIN
wp_ot6q6i_term_relationships
ON
(
wposts.ID = wp_ot6q6i_term_relationships.object_id
)
LEFT JOIN
wp_ot6q6i_term_taxonomy
ON
(
wp_ot6q6i_term_relationships.term_taxonomy_id = wp_ot6q6i_term_taxonomy.term_taxonomy_id
)
WHERE
wp_ot6q6i_term_taxonomy.taxonomy = 'product_cat' AND wp_ot6q6i_term_taxonomy.term_id IN(
SELECT
term_id
FROM
`wp_ot6q6i_terms`
WHERE
slug = 'preorder'
)
ORDER BY
wpostmeta.meta_value
) t2
ON
t1.PROD_ID = t2.PROD_ID
)
ORDER BY
wp_ot6q6i_posts.post_date
DESC
LIMIT 0, 20
And the error I'm getting is:
1054 - Unknown column 'wp_ot6q6i_posts.ID' in 'where clause'
Thanks all for your help. I ended up going in a different direction to solve this problem, one I'm more comfortable with as a dev...I'm pulling the fixed list of items from the last join and building a query in code that has a series of more simple queries in the where clause, thereby avoiding the whole Exists approach.
Thanks again for your help.

How to get Wordpress post with title, content and featured image using mysql query

Hi I know this question may seems familiar but please read the full question.
I want to get Wordpress post title,featured image,content using a mysql query.
I tried many queries but I'm getting errors.
there is no error and MySQL query returns empty. I am using Wordpress version 4.5.2.
I found this query but it is giving me an empty result.
SELECT p1.*, wm2.meta_value
FROM wp_posts p1
LEFT JOIN wp_postmeta wm1 ON (
wm1.post_id = p1.id
AND wm1.meta_value IS NOT NULL
AND wm1.meta_key = '_thumbnail_id'
)
LEFT JOIN
wp_postmeta wm2
ON (
wm1.meta_value = wm2.post_id
AND wm2.meta_key = '_wp_attached_file'
AND wm2.meta_value IS NOT NULL
)LEFT JOIN
wp_term_relationships wtr
ON
(
object_id=p1.id
)
WHERE
p1.post_status='publish'
AND p1.post_type='post'
AND 'term_taxonomy_id'='454'
ORDER BY p1.post_date DESC
LIMIT 0,10
How can I improve this query to return results?
You have an error in SQL's WHERE clause:
AND 'term_taxonomy_id'='454'
The string 'term_taxonomy_id' will never be equal to the string '454'.
First, to check, remove this condition entirely from your query. If you get results back and you still want to filter by this taxonomy_id then remove the single quote marks around the field name:
SELECT p1.*,
wm2.meta_value
FROM wp_posts p1
LEFT JOIN wp_postmeta wm1 ON (
wm1.post_id = p1.id
AND wm1.meta_value IS NOT NULL
AND wm1.meta_key = '_thumbnail_id'
)
LEFT JOIN wp_postmeta wm2 ON (
wm1.meta_value = wm2.post_id
AND wm2.meta_key = '_wp_attached_file'
AND wm2.meta_value IS NOT NULL
)
LEFT JOIN wp_term_relationships wtr ON (object_id = p1.id)
WHERE p1.post_status = 'publish'
AND p1.post_type = 'post'
AND term_taxonomy_id = '454'
ORDER BY p1.post_date DESC LIMIT 0,10
In MySQL you can use backticks around field names, but single quotes are used around string literals. If you mix those up, you'll be in trouble.
If you are still not getting results consider removing the p1.post_status and p1.post_type restrictions to see if you get results back and tweak accordingly.