While working on a project recently that uses WooCommerce & Dokan, I was trying to remove the Inventory section from the Product Edit page. Using Query Monitor I was able to determine that the page template that is being called is new-product-single.php. After some trial and error I found this section of code that removed what I wanted, but it also removed several things I didn’t want it to remove
<?php do_action( 'dokan_product_edit_after_main', $post, $post_id ); ?>
The next thing I did was open up grepWin and figure out where the function ‘dokan_product_edit_after_main‘ was being added. I was able to find it in wp-content/plugins/dokan-lite/includes/Dashboard/Templates/Products.php
add_action( 'dokan_product_edit_after_main', array( __CLASS__, 'load_inventory_template' ), 5, 2 ); add_action( 'dokan_product_edit_after_main', array( __CLASS__, 'load_downloadable_template' ), 10, 2 );
The action I want to remove is called: load_inventory_template(). I tried the following bit of code but it wasn’t working:
add_action('plugins_loaded', 'remove_dokan_inventory', 1); function remove_dokan_inventory() { remove_action( 'dokan_product_edit_after_main', 'load_inventory_template', 5 ); }
I remembered stumbling across a similar problem a while back and decided to give it a try here as well. I created a file called hard-unregister.php and included it in my plugin (or functions.php file of your child theme). The contents of hard-unregister.php are in the gist below. Here’s the working example:
add_action('wp', 'remove_inventory_from_product_edit_page', 1); function remove_inventory_from_product_edit_page() { do_hard_unregister_object_callback('dokan_product_edit_after_main', 5, 'load_inventory_template'); }
When to use it?
When you see this: :: and not this: ->
WeDevs\D\D\T\Products::load_inventory_template()
The normal remove_action() / remove_filter() methods should work if you see this:
Dokan_Geolocation_Vendor_Dashboard->add_product_editor_options()
/** | |
* Do a hard unregister of an object's callback for the specified event name | |
* and priority level. | |
* | |
* In WordPress, the callback key (or unique ID) is generated using the hash ID of | |
* the object concatenated with the method name. In the event that you do not have | |
* the object itself, then we use this hard approach to first first the callback | |
* function and then do the remove. | |
* | |
* This process works for both filter and action events. | |
* | |
* @since 1.0.0 | |
* | |
* @param string $event_name The name of the filter or action event | |
* @param integer $priority Priority level | |
* @param string $method_name Callback's method name | |
* | |
* @return void | |
*/ | |
function do_hard_unregister_object_callback( $event_name, $priority, $method_name ) { | |
$callback_function = get_object_callback_unique_id_from_registry( $event_name, $priority, $method_name ); | |
if ( ! $callback_function ) { | |
return false; | |
} | |
remove_filter( $event_name, $callback_function, $priority ); | |
} | |
/** | |
* Get the object's event registry unique ID for the given event name, priority | |
* level, and method name. | |
* | |
* @since 1.0.0 | |
* | |
* @param string $event_name The name of the filter or action event | |
* @param integer $priority Priority level | |
* @param string $method_name Callback's method name | |
* | |
* @return string|boolean | |
*/ | |
function get_object_callback_unique_id_from_registry( $event_name, $priority, $method_name ) { | |
global $wp_filter; | |
if ( ! isset( $wp_filter[ $event_name ][ $priority ] ) ) { | |
return false; | |
} | |
foreach( $wp_filter[ $event_name ][ $priority ] as $callback_function => $registration ) { | |
if ( strpos( $callback_function, $method_name, 32) !== false) { | |
return $callback_function; | |
} | |
} | |
return false; | |
} |