WordPress - remove action defined within plugin class - php

So I have this plugin code
class WC_List_Grid {
public function __construct() {
add_action( 'wp' , array( $this, 'setup_gridlist' ) , 20);
}
function setup_gridlist() {
add_action( 'woocommerce_before_shop_loop', array( $this, 'gridlist_toggle_button' ), 30);
}
function gridlist_toggle_button() {?>
<nav class="gridlist-toggle">
<span class="dashicons dashicons-grid-view"></span> <em><?php _e( 'Grid view', 'woocommerce-grid-list-toggle' ); ?></em>
<span class="dashicons dashicons-exerpt-view"></span> <em><?php _e( 'List view', 'woocommerce-grid-list-toggle' ); ?></em>
</nav>
<?php }
}
I want to change the content of the gridlist_toggle_button function.
This is how I am planning to change the content of that function. Like writing another function with almost the same html as the original one but bits of my changes. Something like
add_action('woocommerce_before_shop_loop','new_gridlist_toggle_button')
function new_gridlist_toggle_button() {?>
<nav class="gridlist-toggle">
<span class="dashicons dashicons-grid-view"></span> <em><?php _e( 'Grid view', 'woocommerce-grid-list-toggle' ); ?></em>
<span class="dashicons dashicons-exerpt-view"></span> <em><?php _e( 'List view', 'woocommerce-grid-list-toggle' ); ?></em>
</nav>
<?php }
}
That way, I won't have to change the plugin files directly
For that, I am trying to remove its related action.
add_action( 'woocommerce_before_shop_loop', array( $this, 'gridlist_toggle_button' ), 30);
So that I may use my own code. But I can't seem to remove this action. I have tried this so far.
Method 1:
global $WC_List_Grid ;
remove_action( 'woocommerce_before_shop_loop', array( $WC_List_Grid, 'gridlist_toggle_button' ), 100);
Method 2:
function remove_plugin_actions(){
global $WC_List_Grid ;
remove_action( 'woocommerce_before_shop_loop', array( $WC_List_Grid, 'gridlist_toggle_button' ), 100);
}
add_action('init','remove_plugin_actions');
Method 3
remove_action( 'woocommerce_before_shop_loop', array( 'WC_List_Grid', 'gridlist_toggle_button' ), 100);
None of them seems to work.
With a bit of brainstorming, I think there could be two possible causes.
Its not working because the action I want to remove is not directly attached to the hook. Its action inside action.
I am trying to block the output of gridlist_toggle_button via functions.php. But if the plugins load before functions.php then the function to be blocked away is already being called and hence it is always showing output.
I am no good with OOP at all. Can someone please help me out?

Whenever $wc_lg = new WC_List_Grid() is instantiated, its going to trigger wp hook. Right after global WP class object is set up, the instance $wg_lg is going to call setup_gridlist() on itself. Its going to trigger woocommerce_before_shop_loop hook. And whenever that happens, again $wg_lg is going to call a function on itself. Namely gridlist_toggle_button().
I want to change the content of the gridlist_toggle_button function
Why not just to change it inside plugin ? Like override everything whats inside it.
global $WC_List_Grid;
How do you know that $WC_List_Grid has its name? Its just a class name. It can be instantiated under any name like $foo or $bar.
I assume that you are coding in functions.php file of your template. Plugins are being loaded before functions.php and remove_action() can only work after add_action() happend.
Important: To remove a hook, the $function_to_remove and $priority
arguments must match when the hook was added. This goes for both
filters and actions. No warning will be given on removal failure.
http://codex.wordpress.org/Function_Reference/remove_action
So this should actually work just for removing the action, but how that helps you to change content inside of the function? :
remove_action(
'woocommerce_before_shop_loop',
array('WC_List_Grid', 'gridlist_toggle_button'),
30
);
Notice that you were using priority 100
EDIT
I found out that do_action('woocommerce_archive_description') happens in archive-product.php and in wc-template-functions.php right before woocommerce_before_shop_loop hook actions are being executed in plugin. Try to use this:
function remove_plugin_actions(){
global $WC_List_Grid;
remove_action( 'woocommerce_before_shop_loop', array( $WC_List_Grid, 'gridlist_toggle_button' ), 30);
}
add_action('woocommerce_archive_description','remove_plugin_actions');

Related

How do you update or override a non-pluggable function located in woocommerce wc-template-functions

I am building a theme in woocommerce and I have a need to make a small change to the html output by the woocommerce_output_all_notices() in wc-template-functions.php.
The existing function itself is like so:
function woocommerce_output_all_notices() {
echo '<div class="woocommerce-notices-wrapper">';
wc_print_notices();
echo '</div>';
}
What I'd like to do is simply add an id or data attribute and a <span> inside the div, but without editing the code directly (which I clearly don't want to do) I am stumped as it doesn't appear to be a pluggable function and I don't see a way that I can use a hook for this one.
Removing the action that executes the above function should work.
remove_action( 'woocommerce_before_single_product', 'woocommerce_output_all_notices', 10 );
then add a new action that returns what you need
function custom_woocommerce_output_all_notices() {
// Change your code here.
echo '<div class="woocommerce-notices-wrapper">';
wc_print_notices();
echo '</div>';
}
add_action( 'woocommerce_before_single_product', 'custom_woocommerce_output_all_notices', 10 );

Replacing parent action of Custormizr theme

I created my own child theme. Everything works great except I can't seem to unregister a hoook.
$this is class TC_footer_main and the following code is in the __construct
add_action ( '__colophon' , array( $this , 'tc_colophon_center_block' ), 20 );
I tried several remove actions with no success. I am just trying to change/remove the footer:
remove_action( '__colophon' , 'tc_colophon_center_block' , 55);
or
remove_action( '__colophon' , array('TC_footer_main','tc_colophon_center_block') , 55);
I've also tried
remove_action( '__colophon' , TC_footer_main::$instance->tc_colophon_center_block() , 55);
But that threw an error as TC_footer_main was not loaded by the time my functions.php file ran.
I am just trying to change/remove the footer:
I think you're making it way more complex, to modify the output of the tc_colophon_center_block() method, than it has to be.
Just use the tc_credits_display filter:
add_filter( 'tc_credits_display', function( $html )
{
// Modify output to your needs!
return $html;
} );
to modify that block to your needs.
To totally remove the output (if that's allowed), simply use:
add_filter( 'tc_credits_display', '__return_null', PHP_INT_MAX );
You have further access to filters like:
tc_copyright_link
tc_credit_link
tc_wp_powered
to choose from.
That's it!
For your purpose add the following code in function.php. It will get call on after_setup_theme hook.
// replace parent function
function child_theme_function () {
// your code goes here
}
function my_theme_setup () {
remove_action( '__colophon', 'tc_colophon_center_block', 1000 );
add_action( '__colophon', 'child_theme_function', 1000 );
}
add_action( 'after_setup_theme', 'my_theme_setup' );
You can also try for overriding the parent class from child class as described here: https://thethemefoundry.com/tutorials/advanced-customization-replacing-theme-functions/
you werent too far away...one problem you may have is you are trying to remove the hook before it has been added by your parent theme..the class could be initialized at a later stage...
im not too sure when your hook runs, but hopefully its after init
add_action('init', 'remove_parent_hook');
function remove_parent_hook(){
remove_action( '__colophon' , array('TC_footer_main','tc_colophon_center_block') , 20); // needs to be the same priority
}
you can obviously now just add a action for your new function.
There is a offchance that a anonymous function has been added, often the significance of &$this is overlooked when trying to remove a hooked function. This is a pain because wp will assign a random string as the key name & the function name for the function, its different every time so it cant be guessed. But we can search for the function name within the key so something like this will work
function remove_anon_hk($hook, $function, $priority=10 ){
global $wp_filter;
$hooks= $wp_filter[$hook][$priority];
if(empty ($hooks))
return;
foreach($hooks as $hk=>$data):
if(stripos($hk, $function) !== false ){
unset($wp_filter[$hook][$priority][$hk]);
}
endforeach;
}
add_action('init', function(){
remove_anon_hk('__colophon', 'tc_colophon_center_block');
});

add function code into specific php page

I'm trying to add this code into my theme's function.php
function custom_add_author() {
$author = get_the_author();
echo $author;
}
add_action( '???', 'custom_add_author' );
I wanted to add this function code into the specific php named
"author-listing.php"
How can I add this using the correct code?
was it?
add_action( 'author-listing.php', 'custom_add_author' );
If i read your question right..you can just use include() function.
For example at the top of author-listing.php, you can add:
include("function.php");
If you ment a wordpress theme, take alook at the official documentation at: https://developer.wordpress.org/reference/functions/add_action/ there are some more examples as well.
To find out the number and name of arguments for an action, simply
search the code base for the matching do_action() call. For example,
if you are hooking into 'save_post', you would find it in post.php:
<?php do_action( 'save_post', $post_ID, $post, $update ); ?>
Your add_action call would look like:
<?php add_action( 'save_post', 'my_save_post', 10, 3 ); ?>
And your function would be:
function my_save_post( $post_ID, $post, $update ) {
// do stuff here
}

How to remove a WordPress action which uses the current object - $this?

I'm familiar with remove_action when removing an action in WordPress.
To create the action:
add_action( 'action_hook', 'function_name', 10, 3 );
To remove the action:
remove_action( 'action_hook', 'function_name', 10, 3 );
But how can I remove an action which uses the current object? e.g $this
add_action( 'some_action_hook', array( $this, 'some_function' ) );
Ref:
http://codex.wordpress.org/Function_Reference/add_action
http://codex.wordpress.org/Function_Reference/remove_action
Inside class
add_action( 'some_action_hook', array( $this, 'some_function' ) );
Outside class,
With use of global vairable:
global $my_class;
remove_action( 'some_action_hook', array( $my_class, 'some_function' ) );
Using class name:
remove_action( 'some_action_hook', array( 'MyClass', 'some_function' ) );
Reference.
To extend on Rikesh answer: Sadly, using class name will not work. As it says on https://codex.wordpress.org/Function_Reference/remove_action
If an action has been added from within a class, for example by a
plugin, removing it will require accessing the class variable.
This leaves only:
global $my_class;
remove_action( 'some_action_hook', array( $my_class, 'some_function' ) );
Or in case of a singleton class like Jetpack to remove the 'show_development_mode_notice' hook (for example) like this:
remove_action( 'jetpack_notices', array( Jetpack::init(), 'show_development_mode_notice' ) );
Using the class name as suggested by the accepted answer didn't work for me in WordPress 4.5.
You can use these code snippets to remove the action (don't mind it being called "filter" on the project's page) by passing the method name or (a bit safer) the class name and method name: https://github.com/herewithme/wp-filters-extras/

Use "do_shortcode" in a WordPress plugin is not working

I have this plugin installed on my WordPress:
http://wordpress.org/plugins/put/
I’m trying to make a plugin that uses the UI Tabs plugin inside my own plugin.
My plugin code so far:
function load_jquery(){
echo '<link rel=\'stylesheet\' id=\'jquery-ui-tabs-css\' href=\'http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/smoothness/jquery-ui.css?ver=1.9.2\' type=\'text/css\' media=\'all\' />';
}
add_action('wp_head','load_jquery');
function print_tabs(){
echo do_shortcode('[tab name="Tab"]-[/tab]');
echo do_shortcode('[end_tabset]');
}
add_shortcode('print_tabs', 'print_tabs');
Now if I use the [print_tabs] shortcode in a new page, it should look like this:
http://img835.imageshack.us/img835/4905/workingp.png
But it’s not working, and it looks like this:
http://imageshack.us/a/img62/9772/notworkingm.png
What could be the problem here?
The problem, from what I can see in put.php in the Post UI Tabs plugin is that the shortcodes are only added during the "the_content" filter in a function called "on_the_content".
add_filter( 'the_content', array( $this, 'on_the_content' ), 7 ); // Priority 7 - before wpautop
(line 96 of put.php)
And that function looks like:
public function on_the_content( $content ) {
$this->has_tabs = (bool) apply_filters( 'put_decide_has_tabs', $this->has_tabs );
if( !$this->has_tabs )
return $content;
global $shortcode_tags;
// Backup current registered shortcodes and clear them all out
$orig_shortcode_tags = $shortcode_tags;
$shortcode_tags = array();
add_shortcode( 'tab', array( $this, 'on_tab_shortcode' ) );
add_shortcode( 'end_tabset', array( $this, 'on_tab_end_shortcode' ) );
// Do the shortcode(only the tab shortcode is registered at this point)
$content = do_shortcode( $content );
// Put the original shortcodes back
$shortcode_tags = $orig_shortcode_tags;
return $content;
}
(starting at line 118 of put.php)
So, given how this plugin is written by modifying the content with a filter which in turn adds the shortcodes when that filter is run, what you're seeing is probably happening because when you call "do_shortcode" those shortcodes don't actually exist.
What echoing do_shortcode is doing then, is just coughing up the text.
Unfortunately, because of the way the Post UI Tabs plugin is written, you may not be able to do what you're trying to do.

Categories