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
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;
}
}
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;
}
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.
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 );
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;
}