0

I am trying to add a new custom Product Type to WooCommerce by creating a plugin. I have been able to get a new product type available in the admin interface and I have been able to customize the Add/Edit Product pages to have some custom settings.

What I have been unable to do thus far is figure out exactly how to hook/modify the page output when you visit the product page on the site.

I found a couple of pages (here and here) that had some guidance on the topic but I can't seem to get the hook working based on my product type (code at bottom). Maybe I've got the namespace (function or hook names) wrong and that is why it isn't catching?

Plugin Name: WooCommerce Family Product

Plugin Folder: woocommerce-familyproduct

Product Class: WC_Product_Family

Product Type: wcfp_family_product

The following are the references I used for getting started with my plugin to add the custom product type: here, here and here

My plugin code thus far is as follows (some hooks commented out for testing):

<?php

/*
https://wisdmlabs.com/blog/create-product-type-custom-settings-woocommerce/
http://jeroensormani.com/adding-a-custom-woocommerce-product-type/


// Example showing a product select drop down menu on the Settings page of the custom product type:
https://stackoverflow.com/questions/30973651/add-product-search-field-in-woo-commerce-product-page

*/

// add a product type
add_filter( 'product_type_selector', 'wcfp_add_family_product_type' );
function wcfp_add_family_product_type( $types ){
    $types[ 'wcfp_family_product' ] = __( 'Family Product' );
    return $types;
}

add_action( 'plugins_loaded', 'wcfp_create_family_product_type' );
function wcfp_create_family_product_type(){
     // declare the product class
     class WC_Product_Family extends WC_Product{
        public function __construct( $product ) {
           $this->product_type = 'wcfp_family_product';
           parent::__construct( $product );
           // add additional functions here
        }
    }
}






// add the settings under ‘General’ sub-menu
add_action( 'woocommerce_product_options_general_product_data', 'wcfp_add_custom_settings' );
function wcfp_add_custom_settings() {
    global $woocommerce, $post;
    echo '<div class="options_group hidden show_if_wcfp_family_product">';

?>

    <p class="form-field product_field_type">
    <label for="wcfp_family_product_ids"><?php _e( 'Component Products:', 'woocommerce' ); ?></label>

        <input type="hidden" class="wc-product-search" style="width: 50%;" id="wcfp_family_product_ids" name="wcfp_family_product_ids" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
                        $product_ids = array_filter( array_map( 'absint', (array) get_post_meta( $post->ID, '_wcfp_family_product_ids', true ) ) );
                        $json_ids    = array();

                        foreach ( $product_ids as $product_id ) {
                            $product = wc_get_product( $product_id );
                            if ( is_object( $product ) ) {
                                $json_ids[ $product_id ] = wp_kses_post( html_entity_decode( $product->get_formatted_name(), ENT_QUOTES, get_bloginfo( 'charset' ) ) );
                            }
                        }

                        echo esc_attr( json_encode( $json_ids ) );
                    ?>" value="<?php echo implode( ',', array_keys( $json_ids ) ); ?>" /> <?php echo wc_help_tip( __( 'Select component parts to display on the product page.', 'woocommerce' ) ); ?>
    </p>

    <?php



    echo '</div>';
}


add_action( 'woocommerce_process_product_meta', 'wcfp_save_custom_settings' );
function wcfp_save_custom_settings( $post_id ){
    //Save the collection of products
    $my_product_ids    = isset( $_POST['wcfp_family_product_ids'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['wcfp_family_product_ids'] ) ) ) : array();
    update_post_meta( $post_id, '_wcfp_family_product_ids', $my_product_ids  );
}



/**
 * Add a custom product tab.
 */
function wcfp_custom_product_tabs( $tabs) {
    $tabs['rental'] = array(
        'label'     => __( 'Family', 'woocommerce' ),
        'target'    => 'family_options',
        'class'     => array( 'show_if_wcfp_family_product'),
    );
    return $tabs;
}
//add_filter( 'woocommerce_product_data_tabs', 'wcfp_custom_product_tabs' );



/**
 * Hide Attributes data panel.
 */
function wcfp_hide_attributes_data_panel( $tabs) {

    // Other default values for 'attribute' are; general, inventory, shipping, linked_product, variations, advanced
    //$tabs['general']['class'][] = 'hide_if_wcfp_family_product';
    $tabs['inventory']['class'][] = 'hide_if_wcfp_family_product';
    $tabs['shipping']['class'][] = 'hide_if_wcfp_family_product';
    $tabs['linked_product']['class'][] = 'hide_if_wcfp_family_product';
    $tabs['attribute']['class'][] = 'hide_if_wcfp_family_product';
    $tabs['advanced']['class'][] = 'hide_if_wcfp_family_product';

    return $tabs;

}
//add_filter( 'woocommerce_product_data_tabs', 'wcfp_hide_attributes_data_panel' );

I've got creating/editing a product down, you can select which products make up a "Family" product. Now I'm moving on to creating a custom product page that will change what gets rendered out when a customer views the product. Based on my searching, I believe this would be the "add_to_cart" hook.

Now, assuming that the "add_to_cart" function IS what I want to hook, I created a template folder within my plugin and then the PHP script and my code to hook the add_to_cart function was as follows:

function woocommerce_wcfp_family_product_add_to_cart() {
        wc_get_template( WP_PLUGIN_DIR.'/woocommerce-familyproduct/templates/wcfp_family_product.php' );
}
add_action( 'woocommerce_wcfp_family_product_add_to_cart', 'woocommerce_wcfp_family_product_add_to_cart' );

Inside the template file I just have some raw HTML for testing, like a H5 tag, so I know that the hook is firing.

So, what am I doing wrong?

2
  • can you edit your question to make it explicit what is it actually that you are asking about? Sep 17, 2016 at 4:12
  • I've updated the question, hopefully it is more clear what I'm asking about.
    – Nick Bork
    Sep 17, 2016 at 14:23

1 Answer 1

1

The cruxof my issues were a mis-matching class name/product type. I was calling the class WC_Product_Family but using a product type of "wcfp_family_product".

I refactored the code, adding in the hook for the add_to_cart and was able to get a crude working example:

<?php

/*
https://wisdmlabs.com/blog/create-product-type-custom-settings-woocommerce/
http://jeroensormani.com/adding-a-custom-woocommerce-product-type/


// Example showing a product select drop down menu on the Settings page of the custom product type:
http://stackoverflow.com/questions/30973651/add-product-search-field-in-woo-commerce-product-page

*/

// add a product type
add_filter( 'product_type_selector', 'wcfp_add_family_product_type' );
function wcfp_add_family_product_type( $types ){
    $types[ 'familyproduct' ] = __( 'Family Product' );
    return $types;
}

add_action( 'plugins_loaded', 'wcfp_create_family_product_type' );
function wcfp_create_family_product_type(){
     // declare the product class
     class WC_Product_FamilyProduct extends WC_Product{
        public function __construct( $product ) {
           $this->product_type = 'familyproduct';
           parent::__construct( $product );
           // add additional functions here
        }
    }
}






// add the settings under ‘General’ sub-menu
add_action( 'woocommerce_product_options_general_product_data', 'wcfp_add_custom_settings' );
function wcfp_add_custom_settings() {
    global $woocommerce, $post;
    echo '<div class="options_group hidden show_if_familyproduct">';

?>

    <p class="form-field product_field_type">
    <label for="familyproduct_ids"><?php _e( 'Component Products:', 'woocommerce' ); ?></label>

        <input type="hidden" class="wc-product-search" style="width: 50%;" id="familyproduct_ids" name="familyproduct_ids" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
                        $product_ids = array_filter( array_map( 'absint', (array) get_post_meta( $post->ID, '_familyproduct_ids', true ) ) );
                        $json_ids    = array();

                        foreach ( $product_ids as $product_id ) {
                            $product = wc_get_product( $product_id );
                            if ( is_object( $product ) ) {
                                $json_ids[ $product_id ] = wp_kses_post( html_entity_decode( $product->get_formatted_name(), ENT_QUOTES, get_bloginfo( 'charset' ) ) );
                            }
                        }

                        echo esc_attr( json_encode( $json_ids ) );
                    ?>" value="<?php echo implode( ',', array_keys( $json_ids ) ); ?>" /> <?php echo wc_help_tip( __( 'Select component parts to display on the product page.', 'woocommerce' ) ); ?>
    </p>

    <?php



    echo '</div>';
}


add_action( 'woocommerce_process_product_meta', 'wcfp_save_custom_settings' );
function wcfp_save_custom_settings( $post_id ){
    //Save the collection of products
    $my_product_ids    = isset( $_POST['familyproduct_ids'] ) ? array_filter( array_map( 'intval', explode( ',', $_POST['familyproduct_ids'] ) ) ) : array();
    update_post_meta( $post_id, '_familyproduct_ids', $my_product_ids  );
}



/**
 * Add a custom product tab.
 */
function wcfp_custom_product_tabs( $tabs) {
    $tabs['rental'] = array(
        'label'     => __( 'Family', 'woocommerce' ),
        'target'    => 'family_options',
        'class'     => array( 'show_if_familyproduct'),
    );
    return $tabs;
}
//add_filter( 'woocommerce_product_data_tabs', 'wcfp_custom_product_tabs' );



/**
 * Hide Attributes data panel.
 */
function wcfp_hide_attributes_data_panel( $tabs) {

    // Other default values for 'attribute' are; general, inventory, shipping, linked_product, variations, advanced
    //$tabs['general']['class'][] = 'hide_if_familyproduct';
    $tabs['inventory']['class'][] = 'hide_if_familyproduct';
    $tabs['shipping']['class'][] = 'hide_if_familyproduct';
    $tabs['linked_product']['class'][] = 'hide_if_familyproduct';
    $tabs['attribute']['class'][] = 'hide_if_familyproduct';
    $tabs['advanced']['class'][] = 'hide_if_familyproduct';

    return $tabs;

}
//add_filter( 'woocommerce_product_data_tabs', 'wcfp_hide_attributes_data_panel' );

add_action( 'woocommerce_familyproduct_add_to_cart', 'familyproduct_add_to_cart' );
function familyproduct_add_to_cart() {
    echo 'MY CUSTOM ADD TO CART HOOK';
    die();
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.