Faisal Ashfaq
Faisal Ashfaq

Reputation: 2678

WooCommerce creating Product Custom Attributes fields programmatically?

I am trying to add Product Custom Attributes programmatically under the URL field as shown in the figure: enter image description here

I have been able to do it using the following code using transition_post_status action:

add_action('transition_post_status', 'wpa_120062_new_product', 10, 3);

function wpa_120062_new_product($new_status, $old_status, $post){

    if( function_exists( 'wc_get_attribute_taxonomies' ) && ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) ) {

        $defaults = array();

        foreach ( $attribute_taxonomies as $key=>$tax ) {

                $name = wc_attribute_taxonomy_name( $tax->attribute_name );

                $value= get_post_meta( $post->ID , '_product_attributes');

                $defaults[ $name ] = array (
                    'name' => $name,

                    'position' => $key+1,
                    'is_visible' => 1,
                    'is_variation' => 1,
                    'is_taxonomy' => 1,
                );

            update_post_meta( $post->ID , '_product_attributes', $defaults );
        }
    }
}

But the problem here is that transition_post_status hook doesn't work great as it sometimes doesn't complete the loading of fields completely.

I have also tried to use wp action but no success.

How can I make this code work but using a different Hook?

Upvotes: 2

Views: 2661

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253869

There isn"t another hook for this purpose that you could use. But I have added to your function the missing variable global $post and a conditional that filters only new created published products.

add_action('transition_post_status', 'wpa_120062_new_product', 10, 3);
function wpa_120062_new_product($new_status, $old_status, $post){

    global $post;
    if( $old_status != 'publish' && $new_status == 'publish' && !empty($post->ID) 
    && in_array( $post->post_type, array( 'product') ) ) {

        if( function_exists( 'wc_get_attribute_taxonomies' ) && ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) ) {

            $defaults = array();
            foreach ( $attribute_taxonomies as $key=>$tax ) {
                $name = wc_attribute_taxonomy_name( $tax->attribute_name );
                $value= get_post_meta( $post->ID , '_product_attributes');
                $defaults[ $name ] = array (
                    'name' => $name,
                    'position' => $key+1,
                    'is_visible' => 1,
                    'is_variation' => 1,
                    'is_taxonomy' => 1,
                );
                update_post_meta( $post->ID , '_product_attributes', $defaults );
            }
        }
    }
}

In addition (if needed, but I am not sure) you could try to use wp_loaded hook to trigger transition_post_status once, because this hook is fired once WordPress, all plugins, and the theme are fully loaded and instantiated. It can be done this way:

if( function_exists( 'wpa_120062_new_product' ) {
    add_action( 'wp_loaded', 'my_wp_is_loaded' );
    function my_wp_is_loaded(){
        do_action ( 'transition_post_status' );
    }
}

Upvotes: 1

Related Questions