Woocommerce Hook after product insertion in backend - wordpress

I've looked through Woocommerce API Docs to see if there's any way to manipulate the product after it gets inserted in the admin backend of Wordpress but couldn't find any. Maybe I missed it?
I need to pick product data and send it to an external API, and obviously, handle it on update and delete...
Is there any way/hook I can use?

This goes more into what I want. Taken from this answer in WP forum. Thanks to the author
add_action('transition_post_status', 'wpse_110037_new_posts', 10, 3);
function wpse_110037_new_posts($new_status, $old_status, $post) {
if(
$old_status != 'publish'
&& $new_status == 'publish'
&& !empty($post->ID)
&& in_array( $post->post_type,
array( 'product')
)
) {
//add some cde here
}
}

If You add a new product in woocommerce then send product_id
add_action('draft_to_publish','my_product_update');
function my_product_update( $post ) {
if($post->post_type == "product"){
$pid=$post->ID;
//your code
}
}

Related

Wordpress: hook XML-RPC to prevent duplicate posts

I have a wordpress photo blog that reposts images from instagram for me.
The posts are created from an IFTTT applet through XML-RPC.
For some reason duplicate posts are often created (this is a bug thats been around for years and ifttt dont seem to care about it).
To get around this, I create each post with a title containing the unique instagram ID of the photo. I would like to use this to compare the new post_title to existing ones.
I have tried hooking into transition_post_status, this works for normal posting but all posts coming though XML-RPC are still published. They seem to bypass that action.
Can I hook into XML-RPC when it creates the post and prevent it if it has an already existing post_title?
Here is the code that works for normal posts:
add_action('transition_post_status', 'check_for_duplicates', 10, 3);
function check_for_duplicates($new_status, $old_status, $post) {
if('publish' === $new_status && 'publish' !== $old_status && $post->post_type === 'post') {
global $post;
global $wpdb ;
$title = $post->post_title;
$post_id = $post->ID ;
$wtitlequery = "SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post' AND post_title = '{$title}' AND ID != {$post_id} " ;
$wresults = $wpdb->get_results( $wtitlequery) ;
if ( $wresults ) {
$error_message = 'This title is already used. Please choose another';
add_settings_error('post_has_links', '', $error_message, 'error');
settings_errors( 'post_has_links' );
$post->post_status = 'draft';
wp_update_post($post);
wp_die( $error_message );
return;
}
//return $messages;
}
}

How to check WooCommerce thank you page

In Wordpressis_page() can check page by ID,name or by slug but how can we check WooCommerce thank you page whether its a part of checkout page.
Also We have a lot of WooCommerce conditional tags but cant find something solve my issue
for example I try
if(is_page('checkout')) {
//some thing for only checkout page
}else if(is_page('thankyou') && !is_page('checkout')){
//some thing for only thank you page but not on checkout page
}else{
//some thing for all other page
}
This sample code may work:
if ( is_checkout() && !empty( is_wc_endpoint_url('order-received') ) ) {
...
}
I think better to use endpoint like
if ( is_wc_endpoint_url( 'order-received' ) ) {
global $wp;
//Get Order ID
$current_order_id = intval( str_replace( 'checkout/order-received/', '', $wp->request ) );
echo $current_order_id;
}

Trigger action when new post is insert in wordpress

My question is,
Is there any filter or action that trigger when new post is insert in database..?
The reason behind it is I want to add key in post meta when new post is insert from admin side.
I got Action called "save_post" but after refer link .This action trigger in created and update post.
but I only want to add meta key when post is created not at update time
You can use wp_insert_post so you will get post_id as soon as post inserted and you can then use that to add meta_key.
If you are not using wp_insert_post and want to use action then you can simply put below code :
if ( wp_is_post_revision( $post_id ) )
return;
which means that if you are updating the post, then it will return back from function.
EDITED
Method-1 to achieve it.
You can simply check with the get_post method that post is there or not.something like below:
add_action('save_post', 'check_for_post_in_database');
function check_for_post_in_database($post_id) {
//check if the post is in the database or not with get_post( $post_id ) == null
if( get_post( $post_id ) == null ) {
//your code to add meta
}
}
//You can do same thing with publish_post
Method-2 to achieve it.
add_action('publish_post', 'check_for_meta_in_database');
function check_for_meta_in_database($post_id) {
global $wpdb;
$your_meta = get_post_meta($post_id, 'meta_key', true);
if( empty( $your_meta ) && ! wp_is_post_revision( $post_id ) ) {
update_post_meta($post_id, 'meta_key', 'meta_value');
}
}
But as you said there are many meta there, this method will be bit long.
Method-3 to achieve it.
You can do as rnevius suggested which is the one even I would opt. Its like :
add_action( 'transition_post_status', 'check_transition_and_then_add_meta', 10, 3 );
function check_transition_and_then_add_meta( $new_status, $old_status, $post ) {
if ( ( 'draft' === $old_status || 'auto-draft' === $old_status ) && $new_status === 'publish' ) {
add_post_meta($post->ID, 'your_meta_key', 'your_meta_value');
}
}
or else you can do it with draft_to_publish like:
//as rnevius suggested {$old_status}_to_{$new_status}
add_action( 'draft_to_publish', 'add_meta_when_status_change' );
function add_meta_when_status_change() {
add_post_meta($post->ID, 'your_meta_key', 'your_meta_value');
}
You can refer codex for more information about post transition.
You're looking for draft_to_publish.
An {old_status}_to_{new_status} action will execute when a post transitions from {old_status} to {new_status}. The action is accompanied by the $post object.

WooCommerce inquiry if no price available

I'm helping a good friend setting up a WooCommerce shop. Since the shop is going to be bigger and the products are pretty variable and customizable we are not able to provide/configure all prizes from the beginning.
However we would like all products to be in the shop and ad an inquiry lead form in case no price is available.
Since I never programmed with WooCommerce I was wondering that is the right hook to implement such an functionality?
Had the exact same issue and couldn't find a plugin or a solution anywhere so I figured a workaround myself:
You need to edit file
/wp-content/themes/your-theme-name/woocommerce/single-product/add-to-cart/simple.php
(if it's not there just copy it from woocommerce plugin
/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php)
and on line 14 where it says
if ( ! $product->is_purchasable() ) return;
you need to comment it out and write something like
if ( ! $product->is_purchasable() ) {
// put your code here
return;
}
and in the //put your code here line you can enter for example a shortcode for a form or a more complicated solution would be to put code for a button that when clicked will open up a popup form.
Still working on that ;)
Maybe too late, but I have had same issue currently.
Here is there code, Woocommerce uses to check if a product can be purchased:
https://github.com/woocommerce/woocommerce/blob/master/includes/abstracts/abstract-wc-product.php#L1404
Notice about: && '' !== $this->get_price()
/**
* Returns false if the product cannot be bought.
*
* #return bool
*/
public function is_purchasable() {
return apply_filters( 'woocommerce_is_purchasable', $this->exists() && ( 'publish' === $this->get_status() || current_user_can( 'edit_post', $this->get_id() ) ) && '' !== $this->get_price(), $this );
}
So you need to write a filter like this to override default:
add_filter( 'woocommerce_is_purchasable', function ( $is_purchasable, $product ) {
return $product->exists() && ( 'publish' === $product->get_status() || current_user_can( 'edit_post', $product->get_id() ) );
}, 10, 2 );
Try the following code snippet. You just have to put it in your functions.php. You don't need a plugin or to overwrite WooCommerce files in your child theme.
// Inquiry link if no price available
function add_inquiry_link_instead_price( $price, $product ) {
if ( '' === $product->get_price() || 0 == $product->get_price() ) :
return ''.__( 'Jetzt anfragen' ).'';
endif;
}
add_filter( 'woocommerce_get_price_html', 'add_inquiry_link_instead_price', 100, 2 );

password protect wordpress posts with custom post type by default

i try to realize the following: posts with a custom post type should be password-protected by default
i found this which works great
https://wordpress.stackexchange.com/questions/4952/forcing-all-posts-associated-with-a-custom-post-type-to-be-private
but i dont want the posts to be private so i chanced
$post->post_status = 'private';
$post->post_password = 'some_default_password';
to
$post->post_status = 'published';
$post->post_password = 'some_default_password';
but then there is no password protection
how can i get this done?
The following code does this, but it only works when a new post (post_type) is created.
If we don't check for empty($data['post_name']), which indicates that a new post is being created, it locks all posts with the some_default_password password.
Code based in this WordPress StackExchange Q&A.
add_filter( 'wp_insert_post_data' , 'so_13517851_filter_handler' , '99', 2 );
function so_13517851_filter_handler( $data , $postarr )
{
// creating new post and correct post_type
if( empty( $data['post_name'] ) && 'post' == $postarr['post_type'] )
$data[ 'post_password' ] = 'some_default_password';
return $data;
}

Resources